home *** CD-ROM | disk | FTP | other *** search
- comment *
-
- PLOT
-
- Copyright (C) 1984 Dr. Peter G. Aitken
- Department of Physiology
- Duke University Medical Center, Durham, NC 27710
-
- This subroutine uses the IBM color graphics board in the 640 X 200 high
- resolution mode to display analog waveforms that are stored as a series
- of values in an integer array.
-
-
- Format: call plot (grid%,clr%,offset%,scale%,addr%,stp%)
-
- if grid%<>0 a screen grid is plotted;
- if grid%=0 no grid is plotted.
-
- if clr%<>0 the screen is cleared;
- if clr%=0 the screen is not cleared.
-
- offset% sets the vertical offset of the display; normally set
- in the range 0-199.
-
- scale% sets the vertical gain of the display, with smaller
- values of scale% giving more gain.
-
- addr% is the address (i.e., offset within the data segment)
- of the first array element to be plotted.
-
- stp% must equal 1, 2, or 4: it determines if 640 (step%=1),
- 320 (step%=2) or 160 (step%=4) data points are plotted. Value
- not range checked.
-
- *
-
- ;*****************************************************************************
-
- sseg segment stack ;set up stack
- dw 50 DUP (?)
- sseg ends
-
- dseg segment
- ;set up data segment with reserved
- array dw (?) ;memory locations for the 6 para-
- divisor dw (?) ;meters to be passed by the calling
- step dw (?) ;program.
- off_set dw (?)
- clear dw (?)
- grid dw (?)
-
- dseg ends
-
-
- video segment at 0B800H
- video ends
-
-
- cseg segment public 'CODE'
-
- assume cs:cseg,ss:sseg,ds:dseg,es:video
-
- public PLOT ;declare "PLOT" public so it can
- ;be called from another program
- PLOT proc far
- push bp ;save register
-
- ;the next block of code gets the 6 parameters passed by the calling
- ;program and stores them in the proper locations
-
- mov bp,sp
- mov si,[bp]+16
- mov dx,[si]
- mov grid,dx ;1st parameter in GRID
- mov si,[bp]+14
- mov dx,[si]
- mov clear,dx ;2nd parameter in CLEAR
- mov si,[bp]+12
- mov dx,[si]
- mov off_set,dx ;3rd parameter in OFF_SET
- mov si,[bp]+10
- mov dx,[si]
- mov divisor,dx ;4th parameter in DIVISOR
- mov si,[bp]+8
- mov dx,[si]
- mov array,dx ;5th parameter in ARRAY
- mov si,[bp]+6
- mov dx,[si]
- mov step,dx ;6th parameter in STEP
-
- push es ;save es value
- mov dx,0B800H ;point es at video ram
- mov es,dx
-
- ;if CLEAR = 0 jump ahead, if CLEAR <> 0 clear screen.
-
- mov dx,clear
- cmp dx,0
- je no_clear
-
- ;the next 5 lines clear the screen by using the STOSW instruction to
- ;place 0 in all words of video memory.
-
- mov cx,2000H ;video ram word count
- mov ax,0
- mov di,0 ;start at offset 0
- cld ;set forward direction
- rep stosw
-
- ;if GRID <>0 put a grid on the screen - else jump
-
- no_clear: mov dx,grid
- cmp dx,0
- je no_grid
-
- ;first do horizontal grid lines
-
- mov ax,199 ;plot line in row 199
- call horiz
- mov ax,175 ;plot line in row 175, 150,
- N1: call horiz ;etc.
- sub ax,25
- jns N1 ;if dx not < 0, do another
-
- ;now do vertical grid lines
-
- mov cx,639 ;plot line in column 639
- call vert
- mov cx,560 ;plot line in column 560,
- N2: call vert ;480, etc.
- sub cx,80
- jns N2 ;if cx not < 0, do another
-
- ;the next block of code initializes cx, which will count loops, and si,
- ;which is used as an offset pointer within the data array
-
- no_grid: mov cx,640 ;count in cx
- mov ax,1280 ;offset for start of plot will
- cwd ;be 1278 for step=1, 638 for
- idiv step ;step=2, and 318 for step=4
- mov si,ax
- sub si,2
-
- ;now we start to plot
-
- mov bx,array ;put array base address in bx
-
- plot_loop: sub cx,step ;subtract STEP from cx; if
- jcxz done ;the result is less than 0,
- ;we're done.
- mov ax,[bx][si] ;get array element
- cmp divisor,0 ;if divisor=0 jump ahead
- jz no_div
- neg ax ;negate it
- cwd ;convert to double word
- idiv divisor ;divide by scaling factor
- add ax,off_set ;add the offset
-
- ;now ax has the row number, which can range from 0 to 199. The next 4
- ;lines check to see if ax is within this range; if ax is less than 0
- ;or greater than 199 the point is not plotted.
-
- no_div: cmp ax,0
- jl skip
- cmp ax,199
- jg skip
-
- call put_point
-
- skip: sub si,2 ;decrement data pointer to point
- ;at next array element
- jmp plot_loop ;go back and do another
-
- done: pop es
- pop bp
- ret 12
- PLOT endp
-
- ;*************************************************************************
-
- ;subroutines
-
- ;"horiz" places a row of dots across the screen, placing a dot in every
- ;15th column. The calling program must pass the desired row number
- ;(0-199) in ax.
-
- horiz proc near
- mov cx,630 ;starting column number
-
- H1: call put_point
-
- sub cx,15 ;decrement column number
- cmp cx,0 ;if cx>=0 do another
- jge H1
- ret
- horiz endp
-
- ;*******************************************
-
- ;"vert" places a column of dots down the screen, placing a dot in every
- ;6th row. The calling program must pass the desired column number
- ;(0-639) in cx
-
- vert proc near
- mov ax,198 ;starting row number
-
- V1: call put_point
-
- sub ax,6 ;decrement row number
- cmp ax,0 ;if ax>=0 do another
- jge V1
- ret
- vert endp
-
- ;**************************************************************
-
- ;This subroutine puts a point on the high resolution graphics screen.
- ;Enter with Y (0-199) in ax, X (0-639) in cx, and es pointing to
- ;video ram (B800). All registers are preserved.
-
- put_point proc near
-
- push si ;save all registers used
- push bx
- push cx
- push ax
- push cx ;save cx and ax again for
- push ax ;program use
-
- and ax,0FEh ;strip off odd/even bit of Y
- sal ax,1
- sal ax,1
- sal ax,1 ;ax=ax times 8
- mov bx,ax
- sal ax,1
- sal ax,1 ;ax=ax times 32
- add ax,bx ;ax=ax times 40
- pop bx ;now bx has original ax
- sar bx,1 ;low bit into CF
- jnb even ;if low bit was 0, y is even
- add ax,2000H ;if odd, adjust for video odd
- ;row addresses
-
- ; now ax has 40*Y if Y is even and 40*Y+2000H if Y is odd - this is the
- ;address of the leftmost video byte in the row in which this point is
- ;to be put. We now must add (X/8) to get actual address
-
- even: sar cx,1
- sar cx,1
- sar cx,1 ;cx=x/8
- add ax,cx ;now ax has final address
- mov si,ax
- pop cx ;now cx has original x
-
- ;now to determine the bit to set
-
- and cx,0007H ;now bx has x mod 8
- mov al,80H ;start with mask 10000000B
- shr al,cl ;shift bit right to correct
- ;position
- or al,es:[si] ;put in any other bits that
- ;are already set in that
- ;byte of video ram
- mov es:[si],al ;put it back in video ram
-
- pop ax
- pop cx
- pop bx
- pop si
- ret
-
- put_point endp
-
- ;**********************************************************************
-
- cseg ends
- end
-