| ECE 291 | Computer Engineering II | Lockwood, Spring 1998 |
| Assigned | Thursday 1/29/98 |
| Due Date | Tuesday 2/10/98 |
| Purpose | Loops, Array manipulation |
| Points | 50 |
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|_|
| | | | |
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
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 |
This assignment has five procedures. You will receive credit by replacing each of these five procedures list below with your own code.
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