ECE 291 Computer Engineering II Lockwood, Spring 1998

Machine Problem 1

Assigned Thursday 1/29/98
Due Date Tuesday 2/10/98
Purpose Loops, Array manipulation
Points 50

Introduction

If you have ever used an computer image editing program such as Corel Draw or PhotoShop, then you are probably familiar with basic graphics editing features. In this machine problem, you will be given the opportunity to write your own image manipulation program for ASCII graphics. Your editing program will support the following features: printing images to the screen, flipping image horizontally, transposing images, rotating images, and cropping images.

ASCII art are images represented only with ASCII characters. A number of images are included with this machine problem. A collection of ASCII artwork can be found on-line at: http://www.yahoo.com/Arts/Visual_Arts/Computer_Generated/ASCII_Art/. Feel free to modify existing artwork files, import artwork from the web, or create your own original images. A sample image (20x20) is shown below:

   _,---,,,_     
 (         ))     
(            )   
(            )    
(_(_((((     )   
 (    , \    )    
 |   /   )   )
 |\ /    (   )
 (.(.)    S  )
  /_       \ )
 /__)   ^   \/
   /____/    |
  )______    |
         \   |
       __-\__|-__
      (          )
      |_|ECE291|_|
      | |      | |

Description

The ASCII art will be entered through an INCLUDE file. Include files are read into the source at assemble time.The include file contains two variables: asciisize and asciidata. All images are square, and may have any image size between 1 and 20. A another sample include file is shown below:

small291.dat
; ASCIIArt for mp1, Spring98
; (Must be a square drawing)

asciisize dw 5

asciidata db '12345'
          db '6789A'
          db 'BCDEF'
          db 'GHIJK'
          db 'LMNOP'

Images for this MP will be stored in an array. Simply put, an array is a series of contiguous memory locations that can be addressed via an integer index. What this means is, once you find the beginning of an array, you can address any member of the array by adding its position relative to the beginning of the array.  The ascii image is stored in a large array called asciidata, in row major format. Take, for example, an image of size 5. (asciisize = 5). This means our image is a 5 x 5 square. Because an ascii character is one byte, this image takes 25 bytes of memory. The top left corner is array index 0, while the bottom corner is array index 24. Here is a visual picture of the array :

Index 0 Index 1 Index 2 Index 3 Index 4
Index 5 Index 6 Index 7 Index 8 Index 9
Index 10 Index 11 Index 12 Index 13 Index 14
Index 15 Index 16 Index 17 Index 18 Index 19
Index 20 Index 21 Index 22 Index 23 Index 24

Now, if you wanted to set the 2nd row, 3rd column to be the ascii character 'z', you would find that its index value is 7. To move L into it you could use the command:

mov  byte ptr [offset asciidata + 7], 'z'

or (equivalently),

mov  asciidata[7],'z'

For more information on arrays, see http://webster.ucr.edu/Page_asm/ArtofAssembly/CH05/CH05-2.html#HEADING2-55

Commands

All commands for this program are entered on the command line. A summary of the command set is shown below:

Command Line Options
Usage: MP1 htrpc#
  p = print ascii picture
  h = horizontal flip
  t = transpose
  r = rotate 90 degrees clockwise
  c# = crop, # = number of "pixels" (0-9)

The array can be printed by using the 'p' command. This will call the PrintArt routine to dump the contents of the asciidata on to the screen. To flip the array horizontally then see the result, you would run: MP1 hp (note that all commands are entered in lower case). You can put as many commands on a line as you wish - each command is run sequentially. If you wanted to crop by 3, print to the screen, then flip horizontally, you would type MP1 c3php. You will not be responsible for implementing the command line parsing, that code is given to you. Instead, you are responsible for writing each of the five main functions - print art, flip horizontal, transpose, rotate and crop. These functions will be directly manipulating the asciidata arrays.

Results from running each of the commands on a 5x5 array are shown below:

Orig.
Input
Flip
Horiz.
Trans-
pose
Rotate Crop 1
 12345 
 6789A
 BCDEF
 GHIJK
 LMNOP
 54321 
 A9876
 FEDCB
 KJIHG
 PONML
 16BGL 
 27CHM
 38DIN
 49EJO
 5AFKP
 LGB61 
 MHC72
 NID83
 OJE94
 PKFA5
   
  789  
  CDE 
  HIJ 
 
MP1 p MP1 hp MP1 tp MP1 rp MP1 c1p

Hints

Procedures

This assignment has five procedures. You will receive credit by replacing each of these five procedures list below with your own code.

Preliminary Procedure

Final Steps

  1. Print a copy of the MP1 grading report (MP1GR) double-check that your program is ready for demonstration.
  2. Demonstrate your MP1.EXE to a TA or to the instructor. You will then be asked to recompile and demonstrate MP1 with different ascii art files. Your program must work with all given input.
  3. Be prepared to answer questions about any aspect of the operation of your program. The TAs will not accept an MP if you cannot fully explain the operation of your code and details of your implementation. Delayed MPs will be subject to late penalties.
  4. Print MP1.ASM
  5. Take your printout and disk with MP1 to the same TA which approved your demonstration. Staple the grading sheet to the front of the MP1.ASM prinout. Be sure that your name is appears in your code and on the grading sheet.

MP1.ASM (program framework)

        PAGE 75, 132
        TITLE AsciiShop - Your Name - Current Date

COMMENT %
        AsciiShop
        --------------------
        ECE291: MP1
        Prof. John W. Lockwood
        Unversity of Illinois, Dept. of Electrical & Computer Engineering
        Assistant Guest Authors: Carlos Manzanedo, Neil Kumar
        Spring 1998
        Revision 1.0
        %

;====== Constants =========================================================

CR      EQU 13
LF      EQU 10

;====== Externals =========================================================

; -- LIB291 Routines (free) --

  extrn binasc:near  ; From lib291.lib (You can use these functions freely)
  extrn dspout:near  ; See your lab manual for a full description
  extrn dspmsg:near  ; of each function

; -- LIBMP1 Routines (replace these with your own code) --

  extrn PrintArt:near       
  extrn FlipHorizontal:near  ; Comment out each line as you   
  extrn TransPose:near       ; write the function
  extrn Rotate:near        
  extrn CropIt:near        

  extrn mp1xit:near  ; Terminates Program      

;====== Stack Segment =====================================================
stkseg  segment stack
        db 64 dup ('STACK   ')
stkseg  ends

;====== Code/Data segment =================================================
cseg    segment public 'CODE' 
        assume  cs:cseg, ds:cseg, ss:stkseg, es:nothing

;====== Variables =========================================================

; The INCLUDE directive inserts the contents of the file into your program.
; In this file, two variables are defined: asciisize and asciidata.
; Choose your test case by un-commenting one of the lines below:

;INCLUDE hextest.dat    ; Tiny (4x4) Array, great for testing
;INCLUDE small291.dat   ; Small (5x5) Array, as shown in MP writeup
;INCLUDE beavis.dat     ; Large (20x20) ASCII Art Image
INCLUDE ece291.dat     ; Large (20x20) ECE291 test array


ErrorMessage  db      'Syntax Error',CR,LF
              db      'Usage: MP1 phtrc#',CR,LF
              db      '  p = print ascii picture',CR,LF
              db      '  h = horizontal flip',CR,LF
              db      '  t = transpose',CR,LF
              db      '  r = rotate 90 degrees clockwise',CR,LF
              db      '  c# = crop, # = number of "pixels" (0-9)',CR,LF,'$'

crlf db CR,LF,'$'  ; Carriage Return / Line Feed String

CommandLinePos dw ?
CommandLineLength dw ?
CropFactor db ?

PUBLIC CropFactor     ; Variables must be accessible by LIBMP1
PUBLIC Asciidata
PUBLIC Asciisize

; ======== Your Code ======================================================

; -- Write the code for your subroutines below --
; To use your own code,
; comment out the 'extrn' routine from above and
; uncomment your procedure declaration
                    
;PrintArt Proc near       ; Print the ascii drawing
        ; Your code Goes here!
        ret
;PrintArt ENDP

;FlipHorizontal Proc NEAR ; Flip the asciidata array horizontally
        ; Your code Goes here!
        ret
;FlipHorizontal ENDP

;Transpose proc Near      ; Transpose the asciidata array
        ; Your code Goes here!
        ret
;Transpose ENDP

;Rotate proc near         ; Rotate the asciidata array by 90 degrees
        ; Your code Goes here!
        ret
;Rotate endp

;CropIt Proc NEAR         ; Crop the aray
        ; Your code Goes here!
        ret
;CropIt ENDP


;====== Main procedure ====================================================

main    proc    far

        ; The Main body of the program parses the command
        ; line and invokes each subroutine.  You are given this code.

        mov  ax, ds  ; Command line arguments are read from the PSP
        mov  es, ax  ; (Brey p.380 and Figure Appendix-A5 has details)
                     
        mov  ax, cseg
        mov  ds, ax  ; set DS=CS

        xor  ax, ax                         
        mov  al, byte ptr es:[80h]          ; Read Command Line Length
        mov  CommandLineLength, ax
        cmp  CommandLineLength, 1           ; Terminate for no commands
        jbe  CommandLineError

        mov  CommandLinePos, 1              ; Skip first space
MainLoop:
        mov  si, CommandLinePos
        cmp  si, CommandLineLength
        jae  DoneCommandLine   
        cmp  byte ptr es:[si+81h], 'r'      ; Check for rotate
        jne  NotRotate
        Call Rotate
        inc  CommandLinePos
        jmp  MainLoop
NotRotate:                                  ; Check for crop
        cmp  byte ptr es:[si+81h], 'c'
        jne  NotCrop

        mov  bl, byte ptr es:[si+81h+1]     ; Get cropfactor
        sub  bl, '0'                        ; Convert ascii digit -> number
        cmp  bl, 9
        ja   CommandLineError               ; Rangecheck for (0..9)
        mov  CropFactor, bl
        call CropIt
        add  CommandLinePos,2
        jmp  MainLoop
NotCrop:
        cmp  byte ptr es:[si+81h], 'h'      ; Check for horizontal flip
        jne  NotHoriz
        call FlipHorizontal
        inc  CommandLinePos
        jmp  MainLoop
NotHoriz:
        cmp  byte ptr es:[si+81h], 't'      ; Check for transpose
        jne  NotTrans
        inc  CommandLinePos
        call Transpose
        jmp  MainLoop
NotTrans:
        cmp  byte ptr es:[si+81h], 'p'      ; Check for printart
        jne  NotPrint
        Call PrintArt
        mov  dx,offset crlf                 ; Print a blank line
        call dspmsg
        inc  CommandLinePos
        jmp  MainLoop
NotPrint:
        cmp  byte ptr es:[si+81h], ' '      ; Ignore spaces
        jne  NotSpace
        inc  CommandLinePos
        jmp  MainLoop
NotSpace:
        jne  CommandLineError               ; If not command, must be error

DoneCommandLine:                            ; Normal termination
        call mp1xit

CommandLineError:
        mov   dx, offset ErrorMessage       ; Print Error message and quit
        call  dspmsg                   
        call  mp1xit

main    endp

cseg    ends
        end     main