CW PROG5.S

From Atari Wiki
Jump to navigation Jump to search
;---------------------------------------------------------------------
; THE ST ASSEMBLY LANGUAGE WORKSHOP, VOLUME 2
; PROGRAM 5
;
; COPYRIGHT 1992 BY CLAYTON WALNUM
;---------------------------------------------------------------------

CCONIN		equ	1
PTERM0          equ     0
MSHRINK         equ     74

V_CLRWK		equ	3
V_PLINE		equ	6
VSL_TYPE	equ	15
VSL_WIDTH	equ	16
VSL_COLOR	equ	17
V_OPNVWK	equ	100
V_CLSVWK	equ	101
VSL_ENDS	equ	108

AES_OPCODE      equ     200
VDI_OPCODE	equ	115

;--------------------------------------------------------------------
; MACROS
;--------------------------------------------------------------------

;--------------------------------------------------------------------
; This macro gets a single character from the keyboard, using the
; Cconin GEMDOS function.
;--------------------------------------------------------------------
get_char macro
        move    #CCONIN,-(sp)
        trap    #1
        addq.l  #2,sp
        endm
        
;--------------------------------------------------------------------
; MAIN PROGRAM
;--------------------------------------------------------------------
        text

; Calculate the size of the program area.

        move.l  a7,a5                   ; Save addr of TPA.
        lea     stack,sp                ; Load addr of our stack.
        
        move.l  4(a5),a5                ; Get addr of TPA.              
        move.l  12(a5),d0               ; Get len of text segment.
        add.l   20(a5),d0               ; Add len of data segment.
        add.l   28(a5),d0               ; Add len of BSS segment.
        add.l   #$100,d0                ; Add len of TPA. 

; Release unused memory back to the system.
        
        move.l  d0,-(sp)                ; Push size of program on stack.
        move.l  a5,-(sp)                ; Push program addr on stack.
        clr     -(sp)                   ; Clear dummy word on stack.    
        move    #MSHRINK,-(sp)          ; Push Mshrink opcode.
        trap    #1                      ; Call GEMDOS.
        add.l   #12,sp                  ; Reset stack pointer.

; Clear some fields of the global array.

        clr.l   ap_ptree        
        clr.l   ap_1resv
        clr.l   ap_2resv
        clr.l   ap_3resv
        clr.l   ap_4resv

; Call appl_init to initialize application.

        move.l  #appl_init,apb
        bsr     aes
        cmpi    #$FFFF,ap_id            ; Error?
        beq     end                     ; Yep.  Outta here.

; Get handle to screen device.

	move.l	#graf_handle,apb
	jsr	aes
	move	int_out,gr_handle	; Save screen device handle.

; Open virtual workstation.

	move	#V_OPNVWK,contrl	; v_opnvwk opcode.
	clr	contrl+2		; # of points in pts_in.
	move	#11,contrl+6		; # of ints in int_in.
	move	gr_handle,contrl+12	; Screen device handle.	
	movea.l	#int_in,a5		; Get address of int_in.
	move	#9,d5			; Init loop counter.
loop:
	move	#1,(a5)+		; Place 1 in element of int_in.
	dbra	d5,loop			; Go init next element of int_in.
	move	#2,int_in+20		; Set for raster coordinates.
	jsr	vdi
	move	contrl+12,vws_handle	; Save virtual workstation handle.

; Clear workstation.

	move	#V_CLRWK,contrl		; v_clrwk opcode.
	clr	contrl+2		; # of points in pts_in.
	clr	contrl+6		; # of ints in int_in.
	jsr	vdi

	move	#3,d5			; Init loop counter.
polyline:

; Set line color.

	move	#VSL_COLOR,contrl	; vsl_color opcode.
	clr	contrl+2		; # of points in pts_in.
	move	#1,contrl+6		; # of ints in int_in.
	move	color,int_in		; New line color.
	jsr	vdi
	addq	#1,color

; Set line ends.

	move	#VSL_ENDS,contrl	; vsl_ends opcode.
	clr	contrl+2		; # points in pts_in.
	move	#2,contrl+6		; # ints in int_in.
	move	ends,int_in		; End style for start of line.
	move	ends,int_in+2		; End style for end of line.
	jsr	vdi
	addq	#1,ends

; Set line width.

	move	#VSL_WIDTH,contrl	; vsl_width opcode.
	move	#1,contrl+2		; # points in pts_in.
	clr	contrl+6		; # of ints in int_in.
	move	width,pts_in		; New line width.
	clr	pts_in+2
	jsr	vdi
	addq	#2,width		; calculate next line width.

; Draw polyline.

	move	#V_PLINE,contrl		; v_pline opcode.
	move	#2,contrl+2		; # of points in pts_in.
	clr	contrl+6		; # of ints in int_in.
	move	#30,pts_in		; X coord of first point.
	move	y1,pts_in+2		; Y coord of first point.
	move	#280,pts_in+4		; X coord of second point.
	move	y2,pts_in+6		; Y coord of second point.
	jsr	vdi
	add	#10,y1			; Calculate next Y coords.
	add	#10,y2
	dbra	d5,polyline		; Go draw next line.

; Reset line widths.

	move	#VSL_WIDTH,contrl	; vsl_width opcode.
	move	#1,contrl+2		; # of points in pts_in.
	clr	contrl+6		; # of ints in int_in.
	move	#1,pts_in		; New line width.
	clr	pts_in+2
	jsr	vdi

; Reset line ends.

	move	#VSL_ENDS,contrl	; vsl_ends opcode.
	clr	contrl+2		; # of points in pts_in.
	move	#2,contrl+6		; # of ints in int_in.
	move	#0,int_in		; End style for start of line.
	move	#0,int_in+2		; End style for end of line.
	jsr	vdi

	move	#5,d5			; Init loop counter.
polyline2:

; Set line type.

	move	#VSL_TYPE,contrl	; vsl_type opcode.
	clr	contrl+2		; # of points in pts_in.
	move	#1,contrl+6		; # of ints in int_in.
	move	type,int_in		; Line pattern type.
	jsr	vdi
	addq	#1,type			; Calculate next line type.

; Draw polyline.

	move	#V_PLINE,contrl		; v_pline opcode.
	move	#2,contrl+2		; # of points in pts_in.
	clr	contrl+6		; # of ints in int_in.
	move	#30,pts_in		; X coord of first point.
	move	y1,pts_in+2		; Y coord of first point.
	move	#280,pts_in+4		; X coord of second point.
	move	y2,pts_in+6		; Y coord of second point.
	jsr	vdi
	add	#10,y1			; Calculate next Y coords.
	add	#10,y2
	dbra	d5,polyline2		; Go draw another line.

	get_char	

; Close the virtual workstation.

	move	#V_CLSVWK,contrl	; v_clsvwk opcode.
	clr	contrl+2		; # of points in pts_in.
	clr	contrl+6		; # of ints in int_in.
	jsr	vdi
		
; Close down application.

exit:
        move.l  #appl_exit,apb          ; appl_exit control array.
        bsr     aes
        
end:
        move.w  #PTERM0,-(sp)           ; Back to desktop.
        trap    #1

;--------------------------------------------------------------------
; This subroutine calls the AES.  Before calling this subroutine, the
; program must have correctly initialized the AES control, int_in,
; and addr_in arrays.
;
; Input:        Appropriate values in the int_in, addr_in, and
;               control arrays.
; Output:       Appropriate values in the int_out, addr_out, and
;               global arrays.
; Regs changed: NONE
; Uses: apb, global, int_in, int_out, addr_in, addr_out
;--------------------------------------------------------------------
aes:
        movem.l a0-a7/d0-d7,-(sp)       ; Save registers.
        move.l  #apb,d1                 ; Load addr of apb.
        move.w  #AES_OPCODE,d0          ; Load AES opcode.
        trap    #2                      ; Call AES.
        movem.l (sp)+,a0-a7/d0-d7       ; Restore registers.
        rts

;--------------------------------------------------------------------
; This subroutine calls the VDI. Before calling this subroutine, the
; program must have correctly initialized the VDI contrl, intin,
; and ptsin arrays.
;
; Input:        Appropriate values in the intin, ptsin, and
;               contrl arrays.
; Output:       Appropriate values in the intout and ptsout arrays.
; Regs changed: NONE
; Uses: vpb, intin, intout, ptsin, ptsout
;--------------------------------------------------------------------
vdi:
        movem.l a0-a7/d0-d7,-(sp)       ; Save registers.
        move.l  #vpb,d1                 ; Load addr of vpb.
        move.w  #VDI_OPCODE,d0          ; Load VDI opcode.
        trap    #2                      ; Call VDI.
        movem.l (sp)+,a0-a7/d0-d7       ; Restore registers.
        rts

        data
        
        even

y1:		dc.w	20
y2:		dc.w	20
color:		dc.w	1
type:		dc.w	1
width:		dc.w	1
ends:		dc.w	0

apb:            dc.l    0,global,int_in,int_out,addr_in,addr_out
vpb:		dc.l	contrl,int_in,pts_in,int_out,pts_out

appl_init:      dc.w    10,0,1,0,0
appl_exit:      dc.w    19,0,1,0,0
graf_handle:	dc.w	77,0,5,0,0

        bss

        even

gr_handle:	ds.w	1
vws_handle:	ds.w	1
        
global:
ap_version:     ds.w    1
ap_count:       ds.w    1
ap_id:          ds.w    1
ap_private:     ds.l    1
ap_ptree:       ds.l    1
ap_1resv:       ds.l    1
ap_2resv:       ds.l    1
ap_3resv:       ds.l    1
ap_4resv:       ds.l    1

contrl:		ds.w	12
int_in:         ds.w    128
int_out:        ds.w    128
addr_in:        ds.l    64
addr_out:       ds.l    64
pts_in:		ds.w	128
pts_out:	ds.w	128

                ds.l    255
stack:          ds.l    1


Back to CW_CHAPTER_5