IUP Computer Science
COSC 300 Spring 2000

Project #6
(Due in class 1 May 2000)

You are to write several macros that deal with input and output, to make them part of a macro library, and to compile, link and execute a program that has been written to rely on these macros in order to work. In the PROJECT directory, you will find a file named MYMACROS.MAR that contains four macros designed to deal with input from a file in much the way such input would be handled by C++. Here is a brief description of each macro that you are given and its arguments.

OPENIN		stream, filedesc
This macro is used to open a file for input; it takes two arguments - the first is the name to be associated with the input stream; the second is the label on a fixed length string descriptor for the file's name. OPENIN opens the file and associates it with the stream name. It also defines several storage areas that are used by other macros; these areas have labels that include the stream name as part of the label. These areas are
FLAG'STREAM	an indicator for whether or not the buffer is empty
SIZE'STREAM	holds the number of bytes remaining in the buffer
POS'STREAM	location in the buffer where the next byte will come from
STREAM'BUF	the file buffer (capable of holding 200 bytes)
STREAM		an indicator for whether or not end-of-file has been reached
CLOSEIN		stream
This macro closes the input file and terminates the association of the stream name with the file that was specified in the OPENIN.
READREC		stream
This macro reads one record from the file into the STREAM'BUF area, appends a blank character to the end of the bytes input, sets SIZE'STREAM to the number of bytes read in + 1 for the blank, sets POS'STREAM to zero (beginning of the buffer), and sets FLAG'STREAM to indicate the buffer is not empty. If the attempt to read from the file fails, READREC sets the end-of-file indicator, STREAM.
BEOF		stream, destination
This macro tests the STREAM indicator and branches to the destination if the indicator shows that end of file has been reached.
CHARIN		stream, ch
 
This macro takes the next character from the input stream (the next buffer position) and puts it in ch. If it is necessary to refill the buffer, CHARIN does this. When the last character in the buffer is taken, CHARIN sets FLAG'STREAM to indicate another file read is needed.

You are to add five macros to this library; below are their descriptions.

STRINGIN	stream, string
This macro is to take a sequence of characters from the STREAM and put them into STRING, storing them as a null-terminated string. STRINGIN must skip leading white space (blanks) until a non-blank character is found to begin the string and then put all characters taken into STRING until a blank character is taken. Because of the actions of READREC, even the end of a line is marked by a blank character. The suggested way to write STRINGIN is to use CHARIN in two loops: the first loop skips white space; the second loop takes characters for the string until white space is reached. After moving the characters to STRING, STRINGIN must place a null character (#0 byte) after the last character.
STRLEN		string, length
This macro is to count the number of characters in a null-terminated string at STRING. The suggested way to do this is to make a counting loop that looks for the null character at the end of the string. Then, put the count in LENGTH. You should assume that LENGTH is a longword; however, it may be in memory or a register.
INTIN		stream, number
This macro is to take a sequence of digit characters from the STREAM, convert them to a longword integer and store them at NUMBER. NUMBER may be a label on memory or a register. The suggested way to write INTIN is to use STRINGIN to move a sequence of digit characters into a storage area within INTIN, determine the length of the sequence with STRLEN, and then convert the leading separate numeric string to a longword using the two conversion instructions.
FILEIN		stream, form, location
This macro is to accept a character, string, or longword integer from STREAM and store the value at LOCATION. The value of FORM must be a C(c) to indicate input of a character, S(s) to indicate input of a string, or I(i) to indicate an integer. The suggested way to write FILEIN is to make a decision based on the FORM, using the CHARIN macro to get a character into LOCATION, using the STRINGIN macro to get a string into LOCATION, and using the INTIN macro to get an integer into LOCATION. For characters and integers, LOCATION is allowed to be a register or a memory location; for strings, LOCATION must refer to memory.
SCREENOUT	form, location
This macro is to output (using writestr and writeint) a character, string, or longword integer held at LOCATION to the screen. The basic idea is similar to FILEIN - the value of FORM must be a C(c) to indicate output of a character, S(s) to indicate output of a string, or I(i) to indicate output of an integer. The LOCATION is allowed to be in any reasonable form for integers and characters - memory, register, even literal. The suggested way to write SCREENOUT is to make a decision based on FORM, using writestr to output a character or string (you will have to determine the length of the string with STRLEN) and using writeint to output an integer (you may assume an 11 digit output field).

Use the techniques described in the hints to create the macro library with all of these macros (the given ones and the ones you add). The library must be named MYMACROS.MLB Then, assemble the program P6DEMO.MAR which you will find in the PROJECT directory. This program uses the macros in MYMACROS.MLB extensively. The program reads a file named THEBIRDS.DAT which you will also find in the PROJECT directory; this file is similar to the file used in project #5. You need to copy all three files, MYMACROS.MAR, P6DEMO.MAR, and THEBIRDS.DAT to your own directory.

Hand in all of the following for this project: a .LIS file for P6DEMO.MAR and a simple printout of MYMACROS.MAR. Also, copy the executable for the program (P6DEMO.EXE) to the HANDIN directory giving it a name based on your own name. If I were copying the file, I would give a command like:

COPY  P6DEMO.EXE  HANDIN:WOLFE.EXE
On the next page is a copy of the P6DEMO.MAR file.
 
;   This program works with a file that is similar to the one used in
;   project 5.  This program reads the last name and first name into
;   strings (that work a lot like C++ strings) and then reads in the
;   five bird counts and sums them together.  Finally, the program
;   displays the names (first then last) and the total birds seen for
;   each person.  This program completely relies on macros to work.
;
            .title      filesummary
            .library    /project:iopack/
            .library    /mymacros/
            easyio
            cr=13
            lf=10
first:      .blkb       20                  ; Watcher's first name
last:       .blkb       20                  ; Watcher's last name
count:      .blkl       1                   ; Number of birds seen
crlf:       .asciz      
title:      .asciz      /Watcher's Name           Total Birds/
thefile:    .ascid      /thebirds.dat/
            .entry      start,^m<>
            openin      watch, thefile          ; Open the file
            screenout   s, title                ; Display titles
top:        filein      watch, s, last          ; Read last name
            beof        watch, fini             ; Exit on eof
            movab       last, r6                ; Replace comma
            strlen      last, r1
            addl2       r1, r6
            movb        #^a/ /,  (r6)
            filein      watch, s, first         ; Read first name
            filein      watch, i, r10           ; Make 1st the total
            movl        #4, r6                  ; Set loop counter
again:      filein      watch, i, count         ; Read a bird count
            addl2       count, r10              ; Add to total
            acbl        #1, # 1, r6, again
            screenout   s, first                ; Display first name
            screenout   c, <#^a/ />             ;  One space
            screenout   s, last                 ; Display last name
            strlen      first, r6               ; Display sufficient
            strlen      last, r7                ;  spaces to fill out
            addl2       r6,r7                   ;  to 25 characters
            incl        r7
            subl3       r7,#25,r7               ; Display one space
shift:      screenout   c, <#^a/ />             ;  at a time
            sobgtr      r7, shift
            screenout   i, r10                  ; Display total count
            screenout   s, crlf                 ; Finish the line
            brw         top
fini:       closein     watch
            $exit_s
            .end        start