CW PROG3MAC.S
;--------------------------------------------------------------------- ; THE ST ASSEMBLY LANGUAGE WORKSHOP, VOLUME 2 ; PROGRAM 3 ; ; COPYRIGHT 1992 BY CLAYTON WALNUM ;--------------------------------------------------------------------- .include "MENU.H" R_TREE equ 0 ARROW equ 0 NORMAL equ 1 MN_SELECTED equ 10 NUM_MENUS equ 11 PTERM0 equ 0 APPL_INIT equ 10 APPL_EXIT equ 19 EVNT_MESAG equ 23 MENU_BAR equ 30 MENU_ICHECK equ 31 MENU_IENABLE equ 32 MENU_TNORMAL equ 33 MENU_TEXT equ 34 FORM_ALERT equ 52 MSHRINK equ 74 GRAF_MOUSE equ 78 RSRC_LOAD equ 110 RSRC_FREE equ 111 RSRC_GADDR equ 112 AES_OPCODE equ 200 ;-------------------------------------------------------------------- ; MACROS ;-------------------------------------------------------------------- ;-------------------------------------------------------------------- ; This macro calls up a simple, one-button GEM alert box, using the ; form_alert AES function. It requires two parameters: the default ; button number and the address of the alert-box string. Because this ; alert box will have only one button, the value for the default ; button must be 0 for no default or 1 for button 1. ;-------------------------------------------------------------------- .macro alert move #FORM_ALERT,control0 move #1,control1 move #1,control2 move #1,control3 clr control4 move #\1,int_in0 move.l #\2,addr_in0 bsr aes .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 #APPL_INIT,control0 ; Place opcode in control array. clr control1 ; Load length of init_in. move #1,control2 ; Load length of int_out. clr control3 ; Load length of addr_in. clr control4 ; Load length of addr_out. bsr aes ; Call the AES. cmpi #$FFFF,ap_id ; Error? beq end ; Yep. Outta here. ; Change mouse pointer back to arrow. move #GRAF_MOUSE,control0 move #1,control1 move #1,control2 move #1,control3 clr control4 move #ARROW,int_in0 ; Mouse form number. clr.l addr_in0 ; Use 0 for address of form. bsr aes ; Load resource file. move #RSRC_LOAD,control0 clr control1 move #1,control2 move #1,control3 clr control4 move.l #rsrc_file,addr_in0 ; Addr of resource file name. bsr aes tst int_out0 ; Did the resource load okay? bne rsrc_okay ; Yep. alert 1,alert5 ; "Resource load error!" bra exit ; Get resource address. rsrc_okay: move #RSRC_GADDR,control0 move #2,control1 move #1,control2 clr control3 move #1,control4 move #R_TREE,int_in0 ; Type number of data. move #TREE00,int_in1 ; Array index of data. bsr aes tst int_out0 ; Was there an error? bne addr_okay ; Nope. alert 1,alert6 ; "Resource address error!" bra exit ; Show menu bar. addr_okay: move.l addr_out,menu_adr ; Save addr of menu resource. move #MENU_BAR,control0 move #1,control1 move #1,control2 move #1,control3 clr control4 move #1,int_in0 ; Set flag to show menu. move.l menu_adr,addr_in0 ; Address of menu resource. bsr aes ; Event loop. event_loop: move #EVNT_MESAG,control0 clr control1 move #1,control2 move #1,control3 clr control4 move.l #msgbuf,addr_in0 ; Address of message buffer. bsr aes ; Decipher message. cmpi #MN_SELECTED,msgbuf0 bne event_loop move #NUM_MENUS-1,d5 ; Init loop counter. move d5,d6 ; Init the... add d6,d6 ; index register. lea menu_ids,a5 ; Get addr of ID table. move msgbuf4,d4 ; Get menu ID. find_id: cmp 0(a5,d6),d4 ; Is this the ID? beq found_id ; Yep. subi #2,d6 ; No, so calculate new index... dbra d5,find_id ; and loop back for another try. bra event_loop ; ID not in table. Whoops! found_id: lea menu_vecs,a5 ; Get addr of vector table. add d6,d6 ; Calculate index. move.l 0(a5,d6),a6 ; Get vector. jmp (a6) ; Jump to proper routine. ; Respond to menu item chosen. info: alert 1,alert1 bsr menu_normal bra event_loop load: alert 1,alert2 bsr menu_normal bra event_loop save: alert 1,alert3 bsr menu_normal bra event_loop option1: tst optn1 ; Is Option1 checked? beq setcheck1 ; No. Go add checkmark. clr optn1 ; Yes. Clear checkmark. clr check_flag bra check setcheck1: move #1,optn1 ; Set option1 checkmark. move #1,check_flag bra check option2: tst optn2 ; Is option2 checked? beq setcheck2 ; No. Go add checkmark. clr optn2 ; Yes. Clear checkmark. clr check_flag bra check setcheck2: move #1,optn2 ; Set option2 checkmark move #1,check_flag bra check option3: tst optn3 ; Is option3 checked? beq setcheck3 ; No. Go add checkmark. clr optn3 ; Yes. Clear checkmark. clr check_flag bra check setcheck3: move #1,optn3 ; Set option3 checkmark. move #1,check_flag check: move #MENU_ICHECK,control0 move #2,control1 move #1,control2 move #1,control3 clr control4 move msgbuf4,int_in0 ; Menu item number. move check_flag,int_in1 ; Checkmark flag. move.l menu_adr,addr_in0 ; Address of resource tree. bsr aes bsr menu_normal bra event_loop onoff: tst on ; Are selections on? beq turn_on ; No, so turn them on. lea on_str,a5 ; Yes. Get address of "On." clr on ; Clear flag. bra enable0 turn_on: lea off_str,a5 ; Get address of "Off." move #1,on ; Set flag. enable0: move #2,d5 ; Init loop counter. move #SELECT1,d6 ; Get menu item number. enable1: move #MENU_IENABLE,control0 move #2,control1 move #1,control2 move #1,control3 clr control4 move d6,int_in0 ; Menu item number. move on,int_in1 ; On/Off flag. move.l menu_adr,addr_in0 ; Address of resource tree. bsr aes addi #1,d6 ; Next menu item number. dbra d5,enable1 ; Change text in menu. move #MENU_TEXT,control0 move #1,control1 move #1,control2 move #2,control3 clr control4 move #ONOFF,int_in0 ; Menu item number. move.l menu_adr,addr_in0 ; Address of resource tree. move.l a5,addr_in1 ; Address of new menu string. bsr aes bsr menu_normal bra event_loop select1: move.b #'1',alert4+30 ; Add '1' to alert string. alert 1,alert4 bsr menu_normal bra event_loop select2: move.b #'2',alert4+30 ; Add '2' to alert string. alert 1,alert4 bsr menu_normal bra event_loop select3: move.b #'3',alert4+30 ; Add '3' to alert string. alert 1,alert4 bsr menu_normal bra event_loop ; Remove menu bar. quit: move #MENU_BAR,control0 move #1,control1 move #1,control2 move #1,control3 clr control4 clr int_in0 ; Menu display flag. move.l menu_adr,addr_in0 ; Address of resource tree. bsr aes ; Release resource space. move #RSRC_FREE,control0 clr control1 move #1,control2 clr control3 clr control4 bsr aes ; Close down application. exit: move #APPL_EXIT,control0 move #0,control1 move #1,control2 move #0,control3 move #0,control4 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.l #AES_OPCODE,d0 ; Load AES opcode. trap #2 ; Call AES. movem.l (sp)+,a0-a7/d0-d7 ; Restore registers. rts ;-------------------------------------------------------------------- ; This subroutine unhighlights a menu title. ; ; Input: Menu object # in msgbuf3. ; Address of resource tree in menu_adr. ; Output: Appropriate values in the int_out and global arrays. ; Regs changed: NONE ; Uses: control, int_in, int_out, addr_in, msgbuf3, menu_adr ; Calls: aes ;-------------------------------------------------------------------- menu_normal: move #MENU_TNORMAL,control0 move #2,control1 move #1,control2 move #1,control3 clr control4 move msgbuf3,int_in0 ; Object number of menu title. move #NORMAL,int_in1 ; Highlight flag. move.l menu_adr,addr_in0 ; Address of resource tree. bsr aes rts data even optn1: dc.w 1 optn2: dc.w 0 optn3: dc.w 0 on: dc.w 1 menu_ids: dc.w INFO,LOAD,SAVE,QUIT,OPTION1,OPTION2 dc.w OPTION3,ONOFF,SELECT1,SELECT2,SELECT3 menu_vecs: dc.l info,load,save,quit,option1,option2 dc.l option3,onoff,select1,select2,select3 apb: dc.l control,global,int_in,int_out,addr_in,addr_out rsrc_file: dc.b "MENU.RSC",0 alert1: dc.b "[0][Assembly Language Workshop |" dc.b " Demo program.| | Copyright 1992|" dc.b " by Clayton Walnum][ OK ]",0 alert2: dc.b "[0][You clicked on | LOAD][ OK ]",0 alert3: dc.b "[0][You clicked on | SAVE][ OK ]",0 alert4: dc.b "[0][You clicked on | Select ][ OK ]",0 alert5: dc.b "[0][Resource load error! ][ OK ]",0 alert6: dc.b "[0][Resource address error!][ OK ]",0 off_str: dc.b " Off",0 on_str: dc.b " On",0 bss even menu_adr: ds.l 1 check_flag: ds.w 1 msgbuf: msgbuf0: ds.w 1 msgbuf1: ds.w 1 msgbuf2: ds.w 1 msgbuf3: ds.w 1 msgbuf4: ds.w 1 msgbuf5: ds.w 1 msgbuf6: ds.w 1 msgbuf7: 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 control: control0: ds.w 1 control1: ds.w 1 control2: ds.w 1 control3: ds.w 1 control4: ds.w 1 int_in: int_in0: ds.w 1 int_in1: ds.w 1 int_out: int_out0: ds.w 1 int_out1: ds.w 1 addr_in: addr_in0: ds.l 1 addr_in1: ds.l 1 addr_out: ds.l 1 ds.l 255 stack: ds.l 1
Back to CW_CHAPTER_3