        .PAGE        .IF     EXTERNAL = 1        .LIST        .ENDC        .IF  USERINT = 1;**********************************;  Mini-Graphics Package	  *;  Contributed by Mike Urquhart	  *;  Copyright 1983, 1984 Apple	  *;**********************************;________________________________________________________________________________;;       DRAWDESK:;;	        this routine performs the following sequences:;;	        1.      clears the screen to a white background.;	        2.      makes a menu bar by drawing a single pixel horizontal;		        line across the screen.;	        3.      fills the screen area below the menu bar with the stantard;		        gray shade.;;	        Also has an entry point called CLRDESK that only does item (3).;;   Destroys regs D0-D2,A1,A5-A6;________________________________________________________________________________;;       1.      clear screen to white backgroundDRAWDESK        clr.l   d2        bsr.s   whiten;;       2.      make menu bar borderCLRDESK moveq   #ROWBYTES,d0    ;set length of line = 90 bytes        moveq   #-1,d2	        ;draw a black pattern        move.w  #MENULINE,A1    ;start at offset 1440 address        moveq   #1,d1	        ;draw only 1 pixel line        bsr.s   paint_box;;       set a6 to starting pixel address for grey routine below;       set a5 to limit;        move    #DESKLINE,a6        move    #DESKLMT,a5     ;set limit;;       3.      make the grey background: to make the gray background, alternating;	        rows of $5555 and $AAAA starting with $AAAA are written to the;	        screen area.;gray    MOVE.L  #DESKPATRN,D2   ;set up grey patterngray1   swap    d2	        ;start with the $AAAA pattern        moveq   #1,d1	        ;draw a one pixel high line        move.l  a6,a1	        ;starting pixel address must be in a1 for call        bsr     paint_box@1      add     d0,a6	        ;bump to next pixel line        cmp.w   a5,a6	        ;is a6 less then max?        blt.s   gray1		      ;loop if yes        rts			      ;else done;_________________________________________________________________________;;       subroutine blacken and whiten: clears full screen to black or white;;       Calls:  bsr     blacken	        (no parameters);;	        clr.l   d2;	        bsr     whiten;;       registers used:	  d2.l - contains either FFFFFFFF or 0 on return;			  d0.b - destroyed but contains $5A (90) on return;			  d1.w - destroyed-->should contain 0 on return;			  a1.l - destroyed;;;       This routine calls paint_box, so other registers may be destroyed.;;;_________________________________________________________________________BLACKEN        moveq   #-1,d2		        ;black fill patternwhiten        move.w  #MaxY-1,d1	        ;number of pixels in screen box heigth        moveq   #ROWBYTES,d0	        ;length of screen box is 90 bytes        suba.l  A1,A1		        ;clear A1        bsr.s   paint_box        rts;------------------------------------------------------------------------;  Subroutine to clear only menu bar on desktop;  Inputs:;       None;  Outputs:;       None;  Side Effects:;       None;------------------------------------------------------------------------CLRMENU MOVEM.L D0-D2/A1,-(SP)  ;save regs        MOVEQ   #ROWBYTES,D0    ;width of menu bar is 90 bytes        MOVEQ   #MBARLEN,D1     ;heigth is 15 pixels        MOVEQ   #0,D2	        ;set fill pattern        SUBA.L  A1,A1	        ;upper left corner is at offset 0        BSR.S   PAINT_BOX       ;go do it        MOVEM.L (SP)+,D0-D2/A1  ;restore and        RTS		        ; exit;________________________________________________________________________________;;       Routine paint_box;;       Call:	     BSR   paint_box;		  or;		     BSR   paintb2;;       register setup:;;       D2 must contain a one word fill pattern.;       D0 must contain the width of the box(horizontally) or the length of;		        the line.;       D1 must contain the heigth(vertically of the box) in horizontal pixel;		        rows:;       A1 must contains the screen displacement in the range 0..32670;;       __________________________________;       .				 .;       .	    fill pattern	 . <-------heigth in pixels;       __________________________________;		        ^;		        ........... length horizontally;;       Assumptions:  location SCRNBASE contains the video address;;       registers used-->D0-D3,A0-A2;________________________________________________________________________________PAINT_BOXpaintb1 lea     movinst,A4        bra.s   continverse lea     exclusive,A4cont    ADD.L   SCRNBASE,A1     ;add video address to starting pixel address offset.paintb2        MOVE.L  A2,-(SP)        ;save reg;       do some setup steps;        CLR.L   D3	        ;clear for use        MOVE.W  D0,D3	        ;modify width/length        NEG.l   D3	        ;negate the width/length (D3 = -width/length);;       add the length of one horizontal pixel row-2 to the -width/length;       to derive an offset which can be added to the updated address pointer;       (when it reflects the right corner or end point of the box/line);       in order to arrive at the next row starting address.;        ADDI.l	 #ROWBYTES,D3   ;create displacement for following sequence;;;        MOVE.L  A1,A2	        ;create ending column check address        ADD.L   D0,A2	        ;add length of line to obtain ending column address;;       A1 now points to the left top coordinate of the box or line.;       A2 now points to the right top coordinate of the box or line.;startop        jmp     (A4)	        ;execute the correct operation (EOR or MOVE)movinst        MOVE.w  D2,(A1)+        ;start the sequence        bra.s   compareexclusive        eor.w   D2,(A1)+compare CMP.L   A1,A2	        ;reached the right most point?        BEQ.S   nextline        ;yes        BRA.S   startop;;       YES;nextline        ADD.L   D3,A1	        ;add 1 horizontal line length (5A) minus line length        ADDA    #ROWBYTES,A2    ;to reach the left most point of the box on the	        RM000        SUBQ.W  #1,D1	        ;next horizontal scan line.        BNE.S   startop	        ;loop until done.;        MOVE.L (SP)+,A2	        ;restore and        RTS		        ;return;------------------------------------------------------------------------;  Entry point to set cursor ptrs and make alert box for power cycling;------------------------------------------------------------------------MAKEPCALRT        MOVEQ   #PCROW,D5       ;set row ptr        MOVEQ   #PCCOL,D6       ;and col ptr                                ;then drop into alert box routine;________________________________________________________________________;;       MAKEALERT;;	        This routine creates an alert box with no title.;________________________________________________________________________MAKEALERT        movem.l d0-d1/a1,-(sp)        MOVEQ   #ALRTWIDTH,D0	        ;set parameters for box        MOVE.L  #ALRTHIGH,D1        MOVEA   #ALRTSTRT,A1        bsr.s   makebox        movem.l (sp)+,d0-d1/a1        rts;________________________________________________________________________;;       MAKETEST;;	        This routine creates an alert box for test icon display.;________________________________________________________________________MAKETEST        movem.l d0-d1/a1,-(sp)        MOVEQ   #TSTWWIDTH,D0	        ;set parameters for alert box        MOVEQ   #TSTWHIGH,D1        MOVEA   #TSTWSTRT,A1        BSR.S   MAKEBOX		        ;go draw box        MOVEQ   #TSTMROW,D5	        ;set cursor ptrs        MOVEQ   #TSTMCOL,D6        LEA     CHKMSG,A3	        ;set message ptr        MOVEQ   #-1,D1		        ;append '...' string        BSR     DSPSTRING	        ;and go display it        BSR     DSPCPU		        ;display test icons        BSR     DSPIOB        BSR     DSPMBRD        BSR     DSPXCRD        movem.l (sp)+,d0-d1/a1        rts;________________________________________________________________________;;       MAKEDBOX;;	        This routine creates a dialog box.;________________________________________________________________________MAKEDBOX        movem.l d0-d1/a1,-(sp)        MOVEQ   #DBOXWIDTH,D0	        ;set parameters for dialog box        MOVEQ   #DBOXHIGH,D1        MOVEA   #DBOXSTRT,A1        bsr.s   makebox        movem.l (sp)+,d0-d1/a1        rts;________________________________________________________________________;;       routine makewindow;;	        This routine creates a fixed window of the folder type.;	        The calling routine must provide the address of the;	        string which will be used to fill in the title box.;;       Call:;	        move    <window width>,d0;	        move    <window heigth>,d1;	        move    <upper left corner address>,a1;	        lea     <string address>,a3;	        bsr     makewindow;;       This routine calls makebox;;________________________________________________________________________MAKEWINDOW        movem.l d0-d1/a1,-(sp)        bsr.s   makebox;;       now draw the title box by drawing a single black line across;       the width of the window about 17 pixels from the top edge;        MOVE.L  A1,-(SP)        ;save start point        add.w   #MENULINE,a1        moveq   #1,d1	        ;set heigth of one pixel        moveq   #-1,d2        bsr.s   paint_box        MOVE.L  (SP)+,A1        ;restore start point        bsr     writetitle        movem.l (sp)+,d0-d1/a1  ;restore and return        rts;________________________________________________________________________;;       Routine makebox;;;	        This routine creates a window of either the folder type;	        or the dialog box type.	 Is is the responsibility of;	        the calling process to append the title box and title;	        to the window if it is the folder type.;;       Call:;	        move.w  <window width>,d0	        (range 0..90) even;	        move.w  <window heigth>,d1	        (range 0..364);	        move.w  <startingpixeladdress>,a1       (range 0..32670);	        bsr     makebox;;       registers used: d0,d1,d2,d3,d4,a1,a2;________________________________________________________________________MAKEBOX;;       make the basic window--->no edges  D2 must be set to 0 on call;					   d0 must be set to the width (90 maximum);					   d1 must be set to the heigth (364 maximum);					   A1 must be the offset address (0..32670);;        movem.l d0-d4/a1-a4,-(sp)        movem.l d0-d1/a1,-(sp)	   ;save the heigth and the starting pixel address        clr.l   d2		   ;the pattern        bsr     paint_box;;       now draw the individual edges including the shadow edges on the right;       and bottom of the window;;;       draw bottom horizontal edge;        sub.l   d3,a1        sub.l   d0,a1	        ;a1 is currently equal to the lower right point                                ; of the box so we can subtract the width to                                ; calculate the lower left point of the box.        moveq   #1,d1	        ;set 1 pixel heigth        moveq   #-1,d2	        ;set the line pattern        bsr     paintb2	        ;remember a4 is set up to point to the move.w                                ; instruction;;       draw bottom horizontal shadow;@1      addq    #2,a1	        ;shadow begin offset by 2        moveq   #1,d1	        ;draw a one pixel line        subq    #2,d0        bsr     paintb2	        ;go;;       draw top horizontal edge;@2      movem.l	 (sp)+,d0-d1/a1 ;restore original parameters        movem.l	 d1/a1,-(sp)        moveq   #1,d1	        ;draw a 1 pixel line        bsr     paint_box;;       now draw the right edge plus the right edge's shadow, use a1;       with a column parameter of 0;        movem.l	 (sp)+,d4/a2        moveq   #1,d2        subq    #2,d4        subq    #2,d0        add.l   d0,a1        move.l  d4,d1        clr.l   d0        bsr.s   paint_v        move.w  #182,d0	        ;set one byte offset from right edge        moveq   #7,d2        move.l  d4,d1        bsr.s   paintbit        ;draw first pixel line of the right shadow        move.w  #272,d0        moveq   #6,d2        move.l  d4,d1        subq    #1,d1	        ;reduce heigth by 1 to compensate for shadow offset        bsr.s   paintbit;;       now draw the left vertical edge of the box;        move.l  a2,a1	        ;restore the starting pixel address        add.l   SCRNBASE,a1     ;add in video address        moveq   #90,d0        add.l   d0,a1        move    #32768,d2       ;set the pattern        move.l  d4,d1	        ;the heigth minus two        clr.l   d0	        ;column 0 offset        bsr.s   paint_v        movem.l (sp)+,d0-d4/a1-a4        rts;_________________________________________________________________________;;       Routine paint_v;;       This routine "paints" a vertical column one word wide.;;       Call:   BSR     paint_v;;       register setup:;;       A1 must contain the screen base address.;       D2 must contain a one word pattern.;       D1 must contain the number of pixels in the vertical length of the line;	  in the range 1..364;       D0 must contain the screen word column in the range 0..44;;       Assumptions:  location SCRNBASE contains the video address;;       registers used: D0-D1;________________________________________________________________________;PAINT_Vpaintv1@1      MOVE.W  D2,0(A1,D0.W)   ;write to screen        SUBQ.W  #1,D1	        ;decrement count        BEQ.S   @2	        ;return        ADDI.W  #ROWBYTES,D0    ;bump to next horizontal line        BRA.S   @1	        ;loop to continue writing vertical.;@2      RTS		        ;return;_________________________________________________________________________;;       Routine paintbit;;       This routine "paints" a vertical line one bit wide.;;       Call:   BSR     paintbit;;       register setup:;;       A1 must contain the screen base address.;       D2 must contain the bit number to set;       D1 must contain the number of pixels in the vertical length of the line;	  in the range 1..364;       D0 must contain the screen word column in the range 0..44;;       Assumptions:  location SCRNBASE contains the video address;;       registers used: D0-D1;________________________________________________________________________PAINTBIT@1      bset    d2,0(a1,d0.w)        subq.w  #1,d1	        ;subtract one from heigth        beq.s   @2	        ;done        addi.w  #ROWBYTES,d0    ;increment to next pixel row.        bra.s   @1@2      RTS		        ;return;______________________________________________________________________;;       Routine makebutton --> creates a black lined box of the size;			       specified by the parameters with button;			       "label" and description if specified.;			       Also makes entries in active rectangle;			       table for later use with mouse.;;			       the left top corner is addressed by a1,;			       the alternate keycode is contained in d0.;			       the description is in A3.;			       description location is in A2.;			       '...' string appended to message if d1 nonzero;;;       Call:;;	        move.w  <left/top corner point>,a1;	        move.b  <alternate keycode>,d0;	        lea     <button description>,a3;	        move.l  <description location>,a2;	        <set d1 for '...' string>;	        bsr     makebutn;;       Destroys regs D0-D2,D5,D6,A3;______________________________________________________________________MAKEBUTN        MOVEM.L D1/A2,-(SP)     ;save string indicator and location ptr        LEA     RectTable,A2    ;get ptr to active rect table        MOVE    (A2),D2	        ;get current count of rect's        MULU    #5,D2	        ;five entries per rect        ADD     D2,D2	        ;double for word index        ADDQ    #1,(A2)+        ;incr for new rect        MOVE    D0,0(A2,D2.W)   ;save keycode id for new rect        BSR     KeyToAscii      ;convert keycode to Ascii        MOVE    D0,D4	        ;save for later display;  compute X,Y pixel coordinates from starting address        BSR     GETROWCOL       ;get pixel row, byte col        MULU    #8,D6	        ;convert to pixel col        MOVE    D6,2(A2,D2.W)   ;save upper left X        MOVE    D5,4(A2,D2.W)   ; and Y coordinates        MOVEQ   #BTNWIDTH,D0    ;set button parameters        MOVEQ   #BTNHIGH,D1        BSR.S   DRAWBUTN        ;draw the button        MOVE.L  A1,-(SP)        ;save original val        MOVE    LwrRight,a1     ;compute lower right coordinates        BSR     GETROWCOL       ;get pixel row        MULU    #8,D6	        ;and pixel col        MOVE    D6,6(A2,D2.W)   ;save as X and        MOVE    D5,8(A2,D2.W)   ; Y coordinates        MOVE.L  (SP)+,A1        ;restore starting value;       Add the button label and description        movem.l d0-d4/a1-a3,-(sp)  ;save parameters        lsr.l   #1,d0	        ;divide window width        bsr     getrowcol       ;get the row and column coordinate of                                ;the window corner point        add.l   d0,d6	        ;adjust column pointer        lsr.l   #1,d1	        ;divide window heigth        subq.l  #4,d1	        ;decrement by half font heigth        add.l   d1,d5	        ;adjust row coordinate        SUBQ    #1,D6	        ;go back 1 and        CLR     D0	        ;display apple icon        BSR     DSPVAL        MOVE.L  D4,D0	        ;get char to display        bsr     dspval	        ;and go display alternate keycode        movem.l (sp)+,d0-d4/a1-a3  ;retrieve parameters        MOVEM.L (SP)+,D1/A2	   ;retrieve location and string indicator        MOVE.L  A2,A1	        ;compute output pt for description        BSR     GETROWCOL        BSR     DSPSTRING       ;and display it        RTS;______________________________________________________________________;;       Routine drawbutton --> creates a black lined box of the size;			       specified by the parameters.;;			       the left top corner is addressed by a1,;			       the width is indicated by d0.;			       the heigth is indicated by d1.;;;	      this routine calls paint_box, and paintbit.;;	        inputs:	        d0=window width in bytes (should be even);			        d1=heigth in pixels;			        a1=window left/top corner point as a;				   0..32670 screen offset address.;;       Call:;;	        move.w  <left/top corner point>,a1;	        move.w  <button width>,d0;	        move.w  <button height>,d1;	        bsr     drawbutn;______________________________________________________________________DRAWBUTN        movem.l d0-d4/a1-a3,-(sp)  ;stack the arguments;;;       draw the top edge of the button;        moveq   #-1,d2	        ;set the black bit pattern for paint_box        moveq   #1,d1	        ;set a 1 pixel line        bsr     paint_box;;       draw the right vertical edge of the button;        sub.l   d3,a1	        ;on return from paint_box, a1 points to the                                ;real address of the left point of the next                                ;horizontal pixel line of the button, so d3,                                ;which contains the displacement to the prior                                ;lines right edge is added to the                                ;left point to obtain the correct                                ;address for the right edge.        move.l  4(sp),d1        ;momentarily restore the heigth        clr.l   d0        moveq   #7,d2	        ;set the 1 bit mask for paintbit        bsr.s   paintbit        ;draw the right edge;;       now draw the left edge of the button;        move.l  20(sp),a1       ;restore the original corner point        add.l   SCRNBASE,a1     ;add in the screen window address        move.l  4(sp),d1        ;restore the heigth        clr.l   d0        moveq   #7,d2	        ;set the 1 bit mask for the left edge        bsr.s   paintbit;;       now draw the bottom edge of the button;        add.l   d0,a1	        ;add the displacement to the corner point to arrive                                ;at the correct address of the bottom left corner        move.l  (sp),d0	        ;restore the width        moveq   #1,d1	        ;set the heigth at 1.        moveq   #-1,d2	        ;set the line pattern to black        bsr     paintb2;;       done - save lower right coordinate;        sub.l   d3,a1	        ;get offset address for lower right corner        sub.l   SCRNBASE,a1        move    a1,LwrRight     ;save it        movem.l (sp)+,d0-d4/a1-a3        rts;____________________________________________________________________;;       Routine to redraw the sides of a pulldown menu item.;;       Call:   move.w  <width of box>,d0;	        move.w  <heigth of box>,d1;	        move.l  <pixeladdress>,a1;	        jsr     inversmenuitem;;____________________________________________________________________DRAWSIDES        movem.l d0-d1/a1,-(sp);       redraw the left vertical edge of the pull down menu        add.l   SCRNBASE,a1     ;add in the real video window address        moveq   #7,d2	        ;set the bit for paintbit        clr.l   d0	        ;remember to clear d0.        jsr     paintbit;       redraw the right vertical edge of the pulldownmenu        move.l  (sp),d0	        ;restore the width        move.l  4(sp),d1        ;restore the heigth        add.l   d0,a1	        ;point the pixel address to the top edge of the right side        subq    #1,a1	        ;adjust address to point to byte with actual right edge        clr.l   d0	        ;remember to clear d0 on call.        clr.l   d2	        ;set bit        jsr     paintbit        movem.l (sp)+,d0-d1/a1  ;restore the parameters        rts;______________________________________________________________________;;  MAKEMENU;	        Displays pull down menu when called.  Also makes;	        entries in active rectangle table for each entry.;;  Inputs:  A1 = starting pixel address for menu "box";	    A2 = starting pixel address for menu option message;	    A3 = ptr to menu strings;	    A4 = ptr to menu id's;	    D0 = menu "box" width;	    D1 = menu "box" heigth;	    D4 = # of menu entries;;______________________________________________________________________MAKEMENU        MOVEM.L D0-D3/A0,-(SP)        .IF  BMENU = 0        BSR     MAKEBOX	        ;go make menu "box"        .ENDC        MULU    #8,D0	        ;convert width to pixel count        LEA     RectTable,A0    ;get ptr to active rectangle table        MOVE    (A0)+,D1        ;get rectangle count        CLR.L   D2	        ;clear for use        MOVE.L  #MENUSPC,D3     ;space between menu entries@1      ADDQ    #1,D1	        ;incr rectangle count        MOVE.B  (A4)+,D2        ;get menu entry id        MOVE    D2,(A0)+        ;save in table        BSR.S   GETROWCOL       ;convert address to X,Y coordinates        MULU    #8,D6	        ;convert to pixels        MOVE    D6,(A0)+        ;save upper X coordinate        MOVE    D5,(A0)+        ;save upper Y coordinate        ADD     D0,D6	        ;compute and save        MOVE    D6,(A0)+        ;  lower X coordinate        ADD     #MENUSPC/90,D5  ;compute and save        MOVE    D5,(A0)+        ; lower Y coordinate        MOVE.L  A1,-(SP)        ;save "box" address        MOVE.L  A2,A1	        ;get address for menu message        BSR.S   GETROWCOL       ;compute msg output pt        BSR     DSPMSG	        ;do display        MOVE.L  (SP)+,A1        ;restore address for box        ADD.L   D3,A1	        ;incr to next start pt for rectangle        ADD.L   D3,A2	        ;also incr message address        SUBQ    #1,D4	        ;loop until done        BNE.S   @1        MOVE    D1,RectCnt      ;save new rectangle count        MOVEM.L (SP)+,D0-D3/A0  ;restore regs and exit        RTS;______________________________________________________________________;;       routine writetitle --> writes the title for the window whose;			       left top corner is addressed by a1,;			       whose width is indicated by d0.;;	  To arrive at the correct address to write the title string,;	  the window width and string length must be divided by 2, the;	  result of the string division is subtracted from the width;	  division to arrive at the general byte column position to;	  begin writing the title.;;;	        inputs:	        d0=window width;			        a1=window left/top corner point as a;				   0..32670 screen offset address.;			        a3=title string address;;	        output:	        all registers used are restored.;______________________________________________________________________WRITETITLE        movem.l d0-d6/a0-a6,-(sp)       ;save as many registers as possible        bsr.s   getlength	        ;calculate the length of the string        lsr.l   #1,d0			   ;divide window width        lsr.l   #1,d2			   ;divide string length        sub.l   d2,d0		        ;1/2 width - 1/2 length --->d0        bsr.s   getrowcol	        ;get the row and column coordinate of                                        ;the window corner point        addq    #4,d5		        ;adjust for 4 pixel rows        add.l   d0,d6		        ;adjust column pointer        movem.l d5/d6,-(sp)	        ;stack line/column pointers for later ref        bsr     dspmsg        movem.l (sp)+,d5/d6	        ;restore the parameters        subq    #4,d5		        ;reduce the pixel pointer by 4        subq    #2,d6		        ;backspace the column pointer by 2        andi.w  #$FFFE,d6	        ;round off to nearest word        sub.l   a6,a6		        ;clear a6        bsr     setcrsr2	        ;convert standard row/col to pixel offset        move.l  a6,a1		        ;move to a1;;       restore the string pointer so that its length can be recalculated.;        move.l  40(sp),a3        bsr     getlength	        ;the length is returned in a2 and d2        addq    #1,d2		        ;must round off the length to a word boundary        andi.w  #$FFFE,d2        move.l  d2,d0		        ;set width of inverted window to length..        addq    #4,d0		        ;..of string plus 4        moveq   #15,d1		        ;set the heigth of the window        moveq   #-1,d2		        ;set the mask        bsr     inverse		        ;invert the title        movem.l (sp)+,d0-d6/a0-a6        rts;______________________________________________________________________;;       routine getrowcol --> converts a screen address displacement;			      to row and column coordinates.;;	        inputs:	      a1=screen address in the range 0..32759;	        outputs:      d5 set to row;			      d6 set to byte col (the remainder);;       registers used: d2 (but saved and restored);       registers destroyed: d5,d6 (set to new values);______________________________________________________________________GETROWCOL        move.l  d2,-(sp)        ;save d2        move.l  a1,d2	        ;move the address to d2        divu    #ROWBYTES,d2    ;divide the address by 90 bytes        move    d2,d5	        ;new row        swap    d2        move.w  d2,d6	        ;remainder is column;	 MOVE.L	 A1,D2		 ;now calculate row;	 SUBI.L	 #TOPOFFSET,D2	 ;decr for offset;	 DIVU	 #RBYTES,D2	 ;divide by bytes per char row;	 MOVE	 D2,D5;	 ADDQ	 #1,D5		 ;incr to next row        move.l  (sp)+,d2        ;restore d2        rts		        ;return;______________________________________________________________________;;       routine getlength --> returns a value which is the length of;			      the string referenced by a3.  The;			      string is assumed to be terminated by;			      the null character value.;;	        inputs:	      a3=string address;	        outputs:      d2,a2: string length;;       registers destroyed: d2,a2 (set to new values);______________________________________________________________________GETLENGTH        move.l  a3,a2@1      move.b  (a2)+,d2        ;read a byte        bne.s   @1	        ;continue        sub.l   a3,a2	        ;subtract the beginning from the end.        move.l  a2,d2	        ;move it to d2 for reference        rts		        ;return;---------------------------------------------------------------------;;  Routine to display uncompressed icon.		        CHG008;; INPUTS:;       A2 = pointer to uncompressed icon  (48 x 32 bitmap);       A6 = pointer to (even!) screen address for upper left hand;	     corner of icon; SIDE EFFECTS:;       D0-D1 are trashed;---------------------------------------------------------------------DSPRGICON        MOVEQ   #ICONWIDTH-1,D0 ;set default width	        CHG008        MOVEQ   #ICONHIGH-1,D1  ; and heigth		        CHG008        BSR.S   OUTPUT	        ;and do display		        CHG008        RTS		        ;			        CHG008;______________________________________________________________________;;  Subroutine to display message or icon.;;       The calling routine must provide the pointer to the raw bit map.;;       Call:   load d0 with number of bytes - 1 in the x axis;	        load d1 with the number of pixels - 1 in the y axis;;	        lea  sourcebytes,a2;	        lea  destination,a6;	        jsr or bsr output;;       Returns with d6 updated.;;----------------------------------------------------------------------OUTPUT        MOVEM.L D2-D4/A6,-(SP)  ;save regs        moveq   #90,d3loop0   clr.l   d4        move.w  d0,d2        bra.s   loop2loop1   addq    #1,d4loop2   move.b  (a2)+,0(a6,d4)        dbf     d2,loop1        add.l   d3,a6        dbf     d1,loop0        addq    #1,d6        MOVEM.L (SP)+,D2-D4/A6  ;restore        rts        .PAGE;---------------------------------------------------------------------;;  Routine to display error icon with id #.;; INPUTS:;       D1 = id # to display;       A2 = pointer to compressed icon;       A5 = upper left corner address for icon as;	     offset from screen address;; SIDE EFFECTS:;       D5-D6 are trashed;---------------------------------------------------------------------DSPNUMICON        BSR     DSPALRTICON     ;display the icon        MOVE    #ERRSTRT,A5     ;get icon address offset        BSR.S   DSPNUM	        ;display id # on icon        ADD.L   SCRNBASE,A5     ;get screen address        BSR     DSPBAD	        ;display bad mark over icon        RTS;---------------------------------------------------------------------;;  Routine to display icon id #.;; INPUTS:;       D1 = id # to display;       A2 = pointer to compressed icon;       A5 = upper left corner address for icon as;	     offset from screen address;; SIDE EFFECTS:;       D1/D5-D6/A2-A3 are trashed;---------------------------------------------------------------------DSPNUM  MOVE.L  D0,-(SP)        ;save reg        MOVE.L  A5,A1	        ;convert icon address to row, col        BSR     GETROWCOL        LEA     XCARD,A3        ;slot card icon?        CMPA.L  A2,A3        BNE.S   @1	        ;skip if not        ADD     #SLOTROW,D5     ;add offsets for card id to cursor ptrs        ADDQ    #SLOTCOL,D6        BRA.S   @6@1      LEA     MEMBRD,A3       ;memory board?        CMPA.L  A2,A3	        ;        BNE.S   @2	        ;skip if not        ADD     #MEMROW,D5      ;add offsets for card id        ADDQ    #MEMCOL,D6        BRA.S   @6	        ;and go display@2      TST.B   SYSTYPE	        ;Lisa 2 system?		        CHG009        BNE.S   @99	        ;exit if yes - no id #'s        CHG009        LEA     DISKETTE,A3     ;diskette icon?        CMPA.L  A2,A3        BNE.S   @3        ADD     #DISKROW,D5     ;compute posn for id #        ADDQ    #DISKCOL,D6        BRA.S   @6@3      LEA     DRIVEN,A3       ;drive icon?		        CHG009        CMPA.L  A2,A3	        ;			        CHG009        BNE.S   @4	        ;skip if not		        CHG009        ADDQ    #DRVROW,D5      ;add offsets for id #	        CHG009        ADDQ    #DRVCOL,D6      ;			        CHG009        BRA.S   @6	        ;and go display		        CHG009@4        SUBQ    #INSRTROW,D5    ;must be insert icon	        CHG009/CHG024        ADDQ    #INSRTCOL,D6    ;			        CHG009@6      BSR     SETCRSR	        ;get screen address in A6        SUBQ    #1,D1	        ;check number to display        BNE.S   @7        LEA     ONE,A2	        ;set ptr to # icon        BRA.S   @9@7      SUBQ    #1,D1	        ;is it 2?        BNE.S   @8        LEA     TWO,A2        BRA.S   @9@8      LEA     THREE,A2        ;must be 3@9      MOVEQ   #0,D0	        ;set width - 1        MOVEQ   #4,D1	        ;and heigth - 1        BSR.S   OUTPUT	        ;display it@99     MOVE.L  (SP)+,D0        ;restore reg        RTS		        ;and exit;---------------------------------------------------------------------;;  Routine to display error icon.;; INPUTS:;       A2 = pointer to compressed icon;; SIDE EFFECTS:;       A2/A6, D5-D6 are trashed;---------------------------------------------------------------------DSPERRICON        BSR     MAKEALERT       ;open alert box        MOVEQ   #ERRROW,D5      ;set screen ptrs        MOVEQ   #ERRCOL,D6        BSR     SETCRSR	        ;get screen address in A6        MOVE.L  A6,A5	        ;save it        BSR     DSPICON	        ;go do display of component iconDSPBAD        LEA     CHECKMRK,A2     ;get ptr to check icon        BSR.S   MRGICON	        ;do the merge        LEA     BADMRK,A2       ;get ptr to slash icon        BSR.S   MRGICON	        ;merge it        RTS		        ;and exit;---------------------------------------------------------------------;;  Routine to merge two icons, one over the other.;; INPUTS:;       A2 = ptr to icon to be merged;       A5 = pointer to base icon;; SIDE EFFECTS:;       None;---------------------------------------------------------------------MRGICON MOVEM.L D0-D3/A5-A6,-(SP) ;save regs        MOVE.L  A5,A6	        ;get start address        ADDQ    #6,A6	        ;first display new icon next to other icon        MOVEM.L A5-A6,-(SP)     ;save ptrs        BSR     DSPICON        MOVEM.L (SP)+,A5-A6     ;restore ptrs        MOVEQ   #ROWBYTES-6,D3  ;set up row offset constant        MOVEQ   #32-1,D2        ;icon heigth in pixel lines - 1@1      MOVEQ   #3-1,D1	        ;icon width in words - 1@2      MOVE    (A6),D0	        ;get from byte        OR      D0,(A5)+        ;do the merge        CLR     (A6)+	        ;erase the old        DBF     D1,@2	        ;do full row        ADDA.L  D3,A5	        ;bump ptrs to next row        ADDA.L  D3,A6        DBF     D2,@1	        ;go to next row        MOVEM.L (SP)+,D0-D3/A5-A6 ;restore and exit        RTS;---------------------------------------------------------------------;;  Routine to display alert icon.;; INPUTS:;       A2 = pointer to icon;	     MSB set if uncompressed icon, else compressed assumed      CHG008;; SIDE EFFECTS:;       A6, D5-D6 are trashed;---------------------------------------------------------------------DSPALRTICON        MOVEM.L D0-D1/A2,-(SP)  ;save regs			        CHG008        BSR     MAKEALERT       ;open alert box        MOVEQ   #ALRTROW,D5     ;set screen ptrs        MOVEQ   #ALRTCOL,D6        BSR     SETCRSR	        ;get screen address in A6        MOVE.L  A2,D1	        ;check icon address		        CHG008        BPL.S   @1	        ;skip if for compressed icon	        CHG008        BCLR    #31,D1	        ;clear indicator bit		        CHG008        MOVE.L  D1,A2	        ;and restore ptr		        CHG008        BSR     DSPRGICON       ;display an uncompressed icon	        CHG008        BRA.S   @2	        ;skip to exit			        CHG008@1      BSR     DSPICON	        ;go do display			        CHG008@2      MOVEM.L (SP)+,D0-D1/A2  ;restore regs			        CHG008        RTS		        ;				        CHG008;---------------------------------------------------------------------;;  Routine to display icon with question mark along side.;; INPUTS:;       A2 = pointer to compressed icon; OUTPUTS:;       A5 = icon screen address; SIDE EFFECTS:;       A2/A6, D5-D6 are trashed;---------------------------------------------------------------------DSPQICON        BSR     MAKEALERT       ;open alert box        MOVEQ   #ERRROW,D5      ;set screen ptrs        MOVEQ   #ERRCOL,D6        BSR     SETCRSR	        ;get screen address in A6        MOVE.L  A6,A5	        ;save it        BSR.S   DSPICON	        ;go do display of component icon        LEA     QUESTION,A2     ;get ptr to ? icon        MOVE.L  A5,A6	        ;restore start address        ADDA    #6,A6	        ;display next to component	        RM000        BSR.S   DSPICON        RTS;---------------------------------------------------------------------;;  Routine to hilite (invert) a test icon.;; INPUTS:;       A1 = address of icon;; SIDE EFFECTS:;       None;---------------------------------------------------------------------INVICON MOVEM.L D0-D2,-(SP)     ;save regs        MOVEQ   #ICONWIDTH,D0   ;set parms for icon        MOVEQ   #ICONHIGH,D1        MOVEQ   #-1,D2	        ;set fill pattern        BSR     INVERSE	        ;and go invert selected one        MOVEM.L (SP)+,D0-D2     ;restore        RTS;---------------------------------------------------------------------;;  Routine to display test icons.;; INPUTS:;       None;; SIDE EFFECTS:;       A2/A6 trashed;---------------------------------------------------------------------DSPCPU        LEA     CPUBRD,A2       ;set ptr for CPU board icon        MOVEA   #CPUSTRT,A6     ;and address        BRA.S   DODSPLY	        ;go do displayDSPMBRD        LEA     MEMBRD,A2       ;set ptr for Memory board icon        MOVEA   #MEMSTRT,A6     ;and address        BRA.S   DODSPLY	        ;go do displayDSPIOB        LEA     IOBRD,A2        ;set ptr for I/O board icon        MOVEA   #IOSTRT,A6      ;and address        BRA.S   DODSPLY	        ;go do displayDSPXCRD        LEA     XCARD,A2        ;set ptr for I/O slot card icon        MOVEA   #XCRDSTRT,A6    ;and addressDODSPLY        ADDA.L  SCRNBASE,A6     ;compute screen address for display        BSR.S   DSPICON	        ;go do display        RTS;---------------------------------------------------------------------;;  Routine to display icon with check mark.;;  Inputs:;       None;  Outputs:;       None; Side Effects:;       A6 trashed;---------------------------------------------------------------------CHKCPU        BSR.S   DSPCPU	        ;redisplay CPU icon        MOVEA   #CPUSTRT,A5     ;get start address for it        BRA.S   DSPCHECK        ;and go add check markCHKMBRD        BSR.S   DSPMBRD	        ;redisplay Memory board icon        MOVEA   #MEMSTRT,A5     ;get start address for it        BRA.S   DSPCHECK        ;and go add check markCHKIOBRD        BSR.S   DSPIOB	        ;redisplay I/O icon        MOVEA   #IOSTRT,A5      ;get start address for it        BRA.S   DSPCHECK        ;and go add check markCHKXCRD        BSR.S   DSPXCRD	        ;redisplay I/O slot card icon        MOVEA   #XCRDSTRT,A5    ;get start address for itDSPCHECK        LEA     CHECKMRK,A2     ;get ptr to check icon        ADDA.L  SCRNBASE,A5     ;compute screen address for display        BSR     MRGICON	        ;and go do merge        RTS;---------------------------------------------------------------------;;  Routine to display compressed icon.;; INPUTS:;       A2 = pointer to compressed icon;       A6 = pointer to (even!) screen address for upper left hand;	     corner of icon; SIDE EFFECTS:;       A6 is trashed;---------------------------------------------------------------------DSPICON        MOVEM.L D0-D2/A0/A2,-(SP)       ;			        CHG009        MOVE.L  A6,A0		        ; save screen start address        MOVEQ   #23,D1		        ; There are 24 octals in an icon        MOVEQ   #5,D2		        ; reset row bytes counterDLOOP   MOVE    #$100,D0	        ; prime D0 for 8 bit count count        MOVE.B  (A2)+,D0	        ; load map byte from compressed imageMLOOP   LSR.W   #1,D0		        ; shift off map bit        BEQ.S   DONE		        ; byte done when = 0        BCC.S   BLACK		        ; dispatch on the bit        CLR.B   (A6)+		        ; store zero in new        BRA.S   CHECK		        ; continue for all 8 bitsBLACK   MOVE.B  (A2)+,(A6)+	        ; store byte in newCHECK   DBF     D2,MLOOP	        ; see if on scanline seam(every 6 bytes)        ADDA    #90-6,A6	        ; bump to next scanline	        RM015        MOVEQ   #5,D2		        ; reset row bytes counter        BRA.S   MLOOP		        ; continue for all 8 bitsDONE    DBF     D1,DLOOP	        ; do the rest of the octals in ICON; Now unXOR the icon on the screen        MOVE.L  A0,A6		        ; get screen pointer saved above        MOVE.L  A6,A2		        ; second pointer        ADDA    #90,A2		        ; scanline pointer	        RM015        MOVE    #30,D1		        ; do 31 scanlines; This is the cause of the even destination restrictionXLOOP   MOVE.L  (A6)+,D0	        ; get long from previous scanline        EOR.L   D0,(A2)+	        ; xor into this scanline        MOVE.W  (A6)+,D0	        ; get word from previous scanline        EOR.W   D0,(A2)+	        ; xor into this scanline        ADDA    #90-6,A2	        ; next scan line + rowbytes     RM015        ADDA    #90-6,A6	        ; next scan line + rowbytes     RM015        DBF     D1,XLOOP        MOVEM.L (SP)+,D0-D2/A0/A2       ;			        CHG009        RTS        .PAGE;----------------------------------------------------------------------;  Subroutine to display text string according to keyboard id;  Inputs:;       A3 = ptr to message;       D1 = nonzero if '...' string to be appended;  Outputs:;       A2 = ptr to start of string;       A3 = ptr to end of string;  Side Effects:;       D5-D6, A3 trashed;----------------------------------------------------------------------DSPSTRING        MOVEM.L D0/D2,-(SP)     ;save regs        LEA     MENUHDG,A2      ;don't translate service mode messages        CMPA.L  A2,A3        BEQ.S   DSPOUT	        ;skip if it is        MOVE.L  A3,A2	        ;else save starting point        MOVE.B  KEYID,D0        ;get keyboard id        BEQ.S   DSPOUT	        ;skip if no id available        ANDI.B  #$3F,D0	        ;clear mfg code        MOVE.B  D0,D2	        ;move to working reg;  Search for US, UK or Canadian keyboard        ANDI.B  #$F0,D2	        ;old US keyboard?        BEQ.S   DSPOUT	        ;yes - go do English display        CMPI.B  #$30,D2	        ;US or Canadian layout?        BNE.S   @1        CMPI.B  #$3D,D0	        ;Canadian?        BEQ.S   DSPALL	        ;yes - display all languages        BRA.S   DSPOUT	        ;else just English@1      CMPI.B  #$20,D2	        ;European keyboard?        BNE.S   DSPALL	        ;no - display all languages        CMPI.B  #$2F,D0	        ;UK?        BEQ.S   DSPOUT	        ;yes - display English;  Search for German type keyboard        CMPI.B  #$2E,D0	        ;German?        BEQ.S   DSPGERMN        CMPI.B  #$26,D0	        ;Swiss-German?        BEQ.S   DSPGERMN;  Search for French type keyboard        CMPI.B  #$2D,D0	        ;French?        BEQ.S   DSPFRNCH        CMPI.B  #$27,D0	        ;Swiss-French?        BEQ.S   DSPFRNCH;  Display all languages for any other keyboard (e.g., Italian, Spanish, etc.)DSPALL  BTST    #MENU,STATFLGS  ;doing menu?        BNE.S   @1	        ;skip if yes        SUB     #CHRSPC,D5      ;back up one row        BSR.S   DSPIT	        ;display English string        ADD     #CHRSPC,D5      ;incr to next row        BSR.S   DSPIT	        ;display French translation        ADD     #CHRSPC,D5      ;bump another row        BRA.S   DSPOUT	        ;go do final display of German@1      BSR.S   DSPMSLSH        ;display English followed by /        BSR.S   DSPMSLSH        ;display French followed by /        BRA.S   DSPOUT	        ;and go do final German displayDSPGERMN        TST.B   (A3)+	        ;skip two strings before output        BNE.S   DSPGERMNDSPFRNCH        TST.B   (A3)+	        ;skip one string before output        BNE.S   DSPFRNCH        MOVE.L  A3,A2	        ;save new beginning ptrDSPOUT  BSR.S   DSPIT	        ;do display        MOVEM.L (SP)+,D0/D2     ;restore regs        RTS		        ; and exit;----------------------------------------------------------------------;  Subroutine to display text string followed by '...';  Inputs:;       A3 = ptr to message;       D1 = nonzero if '...' string to be appended;  Outputs:;       None;  Side Effects:;       A3 updated to next location after 0 byte;----------------------------------------------------------------------DSPIT   MOVEM.L D5-D6,-(SP)     ;save cursor ptrs        BSR.S   DSPMSG	        ;output message        MOVE.L  A3,-(SP)        ;save msg ptr        TST     D1	        ;check if periods needed        BEQ.S   @9	        ;skip if not        LEA     PERIODS,A3      ;else do display        BSR.S   DSPMSG@9        MOVE.L  (SP)+,A3        ;restore regs and exit        MOVEM.L (SP)+,D5-D6        RTS;----------------------------------------------------------------------;  Subroutine to display text string followed by '/';  Inputs:;       A3 = ptr to message;  Outputs:;       None;  Side Effects:;       A3 updated to next location after 0 byte;----------------------------------------------------------------------DSPMSLSH        BSR.S   DSPMSG	        ;output message        MOVEQ   #'/',D0	        ;display /        BSR.S   DSPVAL        RTS;----------------------------------------------------------------------;  Subroutine to display alert box message;  Inputs:;       A3 = ptr to message;  Outputs:;       None;----------------------------------------------------------------------DSPALRTMSG        MOVEM.L D4-D6,-(SP)     ;save regs			        CHG005        MOVE    #MSGROW,D5      ;set screen ptrs        MOVEQ   #MSGCOL,D6        MOVE    D5,D4	        ;set left margin in case of CR	        CHG005        BSR.S   DSPMSG	        ;go do display        MOVEM.L (SP)+,D4-D6     ;restore regs			        CHG005        RTS;----------------------------------------------------------------------;  Routine to convert row coordinate to pixel row coordinate before;  doing message display;;  Expects D5 = row coordinate from 0-32;----------------------------------------------------------------------CONVRTD5        MULU    #10,D5		        ;multiply by pixel lines per char row        BSR.S   DSPMSG		        ;then go do message        RTS        .ENDC			        ;{USERINT};----------------------------------------------------------------------;  Subroutine to display message followed by a line feed, CR.;  Calls DSPMSG routine, with same assumptions as that routine.;----------------------------------------------------------------------DSPMSGR BSR.S   DSPMSG	        ;go display msg        .IF USERINT = 0        ADDQ    #1,D5	        ;do "line feed"        .ELSE        ADD     #CHRSPC,D5      ;do "line feed"        .ENDC        MOVEQ   #1,D6	        ;and "carriage return"        RTS;---------------------------------------------------------------------------; Subroutine to display message on screen.; Requires inputs:;       A3 - ptr to ASCII character string ended by 0 byte;       D4 = left margin if message has a CR;       D5 = cursor row position (0 - 32 decimal);       D6 = cursor column position (1 - 88 decimal); Uses regs:;       D0 - for character to display;; NOTE: ONLY UPPER CASE ALPHA, NUMERIC AND CERTAIN SPECIAL CHARS SUPPORTED!;---------------------------------------------------------------------------DSPMSG  MOVE.L  D0,-(SP)	        ;save reg        .IF     ROM4K = 0@1      CMPI    #LASTROW,D5	        ;check if out of bounds        BLE.S   @2		        ;skip if OK        BSR     SCROLL		        ;else scroll page        .ENDC@2      CLR.L   D0		        ;clear for use        MOVE.B  (A3)+,D0	        ;get a char to display        BEQ.S   DSPDONE		        ;exit if done        BSR.S   DSPVAL		        ;go do display        BRA.S   @1		        ;continue until doneDSPDONE MOVE.L  (SP)+,D0	        ;restore and exit        RTS        .PAGE;----------------------------------------------------------------------; Subroutine to set cursor position in video page for message display.; Requires inputs:;       D5 = row position (0 - 32 decimal);       D6 = column position (1 - 88 decimal);       location SCRNBASE = base address for video page; Provides output:;       A6 = address for new cursor location;----------------------------------------------------------------------SETCRSR        MOVE.L  SCRNBASE,A6	        ;get base address for screenSETCRSR2        MOVE.L  D0,-(SP)	        ;save reg        CLR.L   D0		        ;use as working reg        .IF  USERINT = 0        MOVE.B  D5,D0		        ;get row coordinate        .ELSE        MOVE    D5,D0		        ;get pixel row        .ENDC        MULU    #RBYTES,D0	        ;compute byte offset;	 .IF  USERINT = 0        ADD     #RBYTES,D0	        ;add one more;	 .ELSE;	 ADD	 #TOPOFFSET,D0		 ;adjust for offset from top of screen;	 .ENDC        ADD.L   A6,D0		        ;add in base screen address        MOVE.L  D0,A6		        ;and save new value        CLR.L   D0        .IF  USERINT = 0        MOVE.B  D6,D0		        ;get col coordinate        .ELSE        MOVE    D6,D0		        ;get pixel col        .ENDC        ADDA.L  D0,A6		        ;add to cursor address        MOVE.L  (SP)+,D0	        ;restore and exit        RTS;------------------------------------------------------------------------; Subroutine to display single ASCII character.; Requires input:;       D0 = character to display;       D4 = left margin if CR char;       D5 = cursor row position (0 - 32 decimal);       D6 = cursor column position (1 - 88 decimal); Returns output:;       D6 = new cursor col position (incremented by 1);------------------------------------------------------------------------DSPVAL  MOVEM.L A2/A6/D0-D1,-(SP)       ;save regs        BSR.S   SETCRSR		        ;set cursor position        ANDI    #$7F,D0		        ;ensure valid        .IF  USERINT = 1        TST.B   D0		        ;apple icon?        BEQ.S   @4        .ENDC        .IF  ROM4K = 0        CMPI.B  #$20,D0		        ;space?        BEQ.S   @3		        ;skip if yes        CMPI.B  #RET,D0		        ;carriage return?        BEQ.S   @5		        ;skip if yes        CMPI.B  #QUESTN,D0	        ;'?' char?        BEQ.S   @6        SUB.B   #$2D,D0		        ;else check if in table        BLT.S   @1        CMPI.B  #$C,D0		        ;numeric char?        BLE.S   @2		        ;skip if yes        SUB.B   #7,D0		        ;else decr for alpha check        CMPI.B  #$D,D0		        ;check if in alpha range        BLT.S   @1		        ;skip if invalid        CMPI.B  #$26,D0		        ;last valid char = 'Z'        BLE.S   @2                              ;skip if OK        .ELSE        SUB.B   #$30,D0		        ;convert to table index        BMI.S   @3		        ;skip if space        CMP.B   #$11,D0		        ;alpha char?        BLT.S   @2		        ;skip if not        SUB.B   #$7,D0		        ;else do further conversion        BRA.S   @2		        ;and go do output        .ENDC        .IF  USERINT = 0@1      LEA     INVCHAR,A2	        ;else set for invalid character        BRA.S   OUTPUT@3      LEA     SPACE,A2	        ;set ptr to space char        BRA.S   OUTPUT@5      ADD     #CHRSPC,D5	        ;set cursor for next row        MOVE    D4,D6		        ;set to left margin        BRA.S   DSPVXIT@2      LSL     #3,D0		        ;convert for table        LEA     FONTTBL(D0),A2	        ;get ptr to char in tableOUTPUT  MOVE.B  (A2)+,(A6)	        ;output bits        MOVE.B  (A2)+,R1(A6)        MOVE.B  (A2)+,R2(A6)        MOVE.B  (A2)+,R3(A6)        MOVE.B  (A2)+,R4(A6)        MOVE.B  (A2)+,R5(A6)        MOVE.B  (A2)+,R6(A6)        MOVE.B  (A2)+,R7(A6)        ADDQ    #1,D6		        ;bump cursor col coordinate        .ELSE@1      LEA     INVCHAR,A2	        ;else set for invalid character        BRA.S   OUT@3      LEA     SPACE,A2	        ;set ptr to space char        BRA.S   OUT@4      LEA     APPLICON,A2	        ; display apple icon        BRA.S   OUT@5      ADD     #CHRSPC,D5	        ;set cursor for next row        MOVE    D4,D6		        ;set to left margin        BRA.S   DSPVXIT@6      LEA     QUESTCH,A2	        ;set ptr to '?' char        BRA.S   OUT@2      MOVE    D0,D1		        ;convert for table (multiply by 6)  CHG017        LSL     #3,D0		        ;mult by 8        SUB     D1,D0		        ; then subtract twice        SUB     D1,D0		        ;				    CHG017        LEA     FONTTBL(D0),A2	        ;get ptr to char in tableout     clr.l   d0		        ;set number of bytes-1 in x direction        moveq   #5,d1		        ;set number of pixels-1 in y direction  CHG017        MOVE.B  #0,R0(A6)	        ;first line always 0		        CHG017        ADDA.L  #RBYTES,A6	        ;bump ptr to next row		        CHG017        bsr     output		        ;output char        MOVE.B  #0,R7(A6)	        ;and add final 0 byte        .ENDCDSPVXIT        MOVEM.L (SP)+,A2/A6/D0-D1       ;restore and exit        RTS        .IF     EXTERNAL = 1        .NOLIST        .ENDC        .PAGE;----------------------------------------------------------------------; CHARACTER FONT TABLE;----------------------------------------------------------------------SPACE    .BYTE    $00,$00,$00,$00,$00,$00   ;  (space)FONTTBL  .IF  ROM4K = 0    .BYTE    $00,$00,$00,$7C,$00,$00   ; code =	 45 '-'    .BYTE    $00,$00,$00,$00,$00,$30   ; code =	 46 '.'    .BYTE    $04,$08,$10,$20,$40,$80   ; code =	 47 '/'  .ENDC    .BYTE    $38,$44,$44,$44,$44,$38   ; code =	 48 '0'    .BYTE    $08,$38,$08,$08,$08,$08   ; code =	 49 '1'    .BYTE    $38,$44,$08,$10,$20,$7C   ; code =	 50 '2'    .BYTE    $38,$44,$18,$04,$44,$38   ; code =	 51 '3'    .BYTE    $08,$18,$28,$48,$7C,$08   ; code =	 52 '4'    .BYTE    $7C,$40,$78,$04,$44,$38   ; code =	 53 '5'    .BYTE    $38,$40,$78,$44,$44,$38   ; code =	 54 '6'    .BYTE    $7C,$08,$10,$10,$20,$20   ; code =	 55 '7'    .BYTE    $38,$44,$38,$44,$44,$38   ; code =	 56 '8'    .BYTE    $38,$44,$44,$3C,$04,$38   ; code =	 57 '9'    .BYTE    $30,$48,$84,$FC,$84,$84   ; code =	 65 'A'    .BYTE    $F8,$84,$F8,$84,$84,$F8   ; code =	 66 'B'    .BYTE    $78,$84,$80,$80,$84,$78   ; code =	 67 'C'    .BYTE    $F8,$84,$84,$84,$84,$F8   ; code =	 68 'D'    .BYTE    $FC,$80,$F8,$80,$80,$FC   ; code =	 69 'E'    .BYTE    $FC,$80,$F8,$80,$80,$80   ; code =	 70 'F'    .BYTE    $78,$84,$80,$9C,$84,$7C   ; code =	 71 'G'    .BYTE    $84,$84,$FC,$84,$84,$84   ; code =	 72 'H'    .BYTE    $38,$10,$10,$10,$10,$38   ; code =	 73 'I'    .BYTE    $1C,$08,$08,$08,$88,$70   ; code =	 74 'J'    .BYTE    $88,$90,$A0,$D0,$88,$84   ; code =	 75 'K'    .BYTE    $80,$80,$80,$80,$80,$FC   ; code =	 76 'L'    .BYTE    $84,$CC,$B4,$84,$84,$84   ; code =	 77 'M'    .BYTE    $84,$C4,$A4,$94,$8C,$84   ; code =	 78 'N'    .BYTE    $78,$84,$84,$84,$84,$78   ; code =	 79 'O'    .BYTE    $F8,$84,$84,$F8,$80,$80   ; code =	 80 'P'    .BYTE    $78,$84,$84,$84,$94,$78   ; code =	 81 'Q'    .BYTE    $F8,$84,$84,$F8,$88,$84   ; code =	 82 'R'    .BYTE    $78,$84,$60,$18,$84,$78   ; code =	 83 'S'    .BYTE    $FE,$10,$10,$10,$10,$10   ; code =	 84 'T'    .BYTE    $84,$84,$84,$84,$84,$78   ; code =	 85 'U'    .BYTE    $44,$44,$28,$28,$10,$10   ; code =	 86 'V'    .BYTE    $82,$82,$92,$AA,$44,$44   ; code =	 87 'W'    .BYTE    $44,$28,$10,$28,$44,$82   ; code =	 88 'X'    .BYTE    $82,$44,$28,$10,$10,$10   ; code =	 89 'Y'    .BYTE    $FC,$08,$10,$20,$40,$FC   ; code =	 90 'Z'  .IF  ROM4K = 0QUESTCH    .BYTE    $38,$44,$08,$10,$00,$10   ; code =	 63 '?'  .ENDCINVCHAR    .BYTE    $C7,$BB,$F7,$EF,$FF,$EF   ;  inverse of ?        .IF  ROM4K = 0APPLICON    .BYTE    $08,$77,$FE,$FE,$7F,$3E   ; apple icon        .PAGE        .ALIGN 2;----------------------------------------------------------------------;  Keycode to Ascii Table  (assumes alpha-lock so upper case only);----------------------------------------------------------------------AsciiTable					 ;				        RM000 .BYTE	 $1B,$2D,$11,$12,$37,$38,$39,$14	 ;Pad : Clear - Left Right 789 Up .BYTE	 $34,$35,$36,$13,$2E,$32,$33,$03	 ;Pad : 456 Down .23 Enter .BYTE	 $00,$00,$00,$00,$00,$00,$00,$00	 ;unused .BYTE	 $00,$00,$00,$00,$00,$00,$00,$00	 ;unused .BYTE	 $2D,$3D,$00,$00,$50,$08,$00,$00	 ;- = 2*unused P BackSp 2*unused .BYTE	 $0D,$30,$00,$00,$2F,$31,$00,$00	 ;Ret Pad:0 2*unused / Pad:1 2*unused .BYTE	 $39,$30,$55,$49,$4A,$4B,$5B,$5D	 ;90UIJK[] .BYTE	 $4D,$4C,$3B,$27,$20,$2C,$2E,$4F	 ;ML;' Space ,.O .BYTE	 $45,$36,$37,$38,$35,$52,$54,$59	 ;E6785RTY .BYTE	 $00,$46,$47,$48,$56,$43,$42,$4E	 ;Option FGHVCBN .BYTE	 $41,$32,$33,$34,$31,$51,$53,$57	 ;A2341QSW .BYTE	 $00,$5A,$58,$44,$00,$00,$00,$00	 ;Tab ZXD unused Alpha Shift Cmd        .ENDC        .IF  USERINT = 1;----------------------------------------------------------------------;  Icons;----------------------------------------------------------------------CrsrData				        ;arrow for mouse cursorCrsrMask				        ;same for mask        .WORD   $8000,$C000,$E000,$F000        .WORD   $F800,$FC00,$FE00,$FF00        .WORD   $F800,$F800,$CC00,$8C00        .WORD   $0600,$0600,$0300,$0300ONE     .BYTE   $E0,$60,$60,$60,$F0	        ;icon id = 1TWO     .BYTE   $E0,$30,$60,$C0,$F0	        ;icon id = 2THREE   .BYTE   $E0,$30,$60,$30,$E0	        ;icon id = 3IObrd	  .BYTE $FF,$FF,$FF,$3F,$03,$FF,$00,$FF          .BYTE $FF,$FF,$E0,$01,$FF,$FF,$FF,$E4          .BYTE $FF,$C0,$70,$2F,$F9,$50,$66,$9E          .BYTE $C0,$01,$80,$F7,$03,$79,$56,$06          .BYTE $74,$FE,$0F,$FF,$FF,$FF,$FF,$FF          .BYTE $FF,$FF,$3F,$01,$AA,$60,$AA,$AF          .BYTE $FF,$C0,$03,$07,$C4,$FF,$E0,$55          .BYTE $55,$50,$F1,$FF,$FF,$F8,$FF,$FFCPUbrd	  .BYTE $FF,$FF,$FF,$3F,$03,$FF,$00,$FF          .BYTE $FF,$FF,$E0,$01,$FF,$FF,$FF,$C4          .BYTE $FF,$C0,$79,$F2,$40,$F9,$38,$E0          .BYTE $BF,$E0,$EF,$F0,$71,$38,$01,$80          .BYTE $79,$FC,$03,$C0,$FF,$FF,$FF,$FF          .BYTE $FF,$FF,$FF,$3F,$01,$FE,$C0,$AA          .BYTE $AA,$BF,$C0,$03,$FC,$84,$1F,$E0          .BYTE $01,$55,$55,$40,$E1,$03,$FF,$FF          .BYTE $E0,$FF,$FFMEMbrd	  .BYTE $FF,$FF,$FF,$FF,$FF,$FF,$C3,$1F          .BYTE $FF,$FF,$C0,$80,$0F,$FF,$FF,$80          .BYTE $07,$FF,$E0,$E3,$03,$FF,$F0,$FF          .BYTE $FF,$FF,$71,$04,$5E,$88,$02,$1C          .BYTE $8E,$50,$03,$8C,$70,$C7,$01,$0C          .BYTE $20,$7B,$0E,$04,$0C,$5E,$88,$03          .BYTE $FF,$D5,$57,$00,$FF,$80,$07,$FF          .BYTE $80,$03,$FF,$C0,$F3,$2A,$A8,$FC          .BYTE $7F,$FC,$FF,$FF,$FF,$FFXcard	  .BYTE $FF,$FF,$FF,$FF,$FF,$FF,$E1,$01          .BYTE $FF,$FF,$80,$FC,$FF,$FF,$FF,$FF          .BYTE $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF          .BYTE $FF,$FF,$DF,$03,$63,$EA,$AD,$80          .BYTE $01,$3C,$C0,$06,$15,$50,$CF,$3F          .BYTE $F8waiticon  .BYTE $FF,$FF,$FF,$61,$1F,$FF,$FF,$F8          .BYTE $0F,$18,$FF,$FF,$F0,$0F,$FF,$FF          .BYTE $86,$F0,$11,$FF,$FF,$88,$6D,$05          .BYTE $A0,$02,$18,$80,$01,$40,$01,$4F          .BYTE $F2,$CE,$80,$A8,$15,$F3,$54,$2A          .BYTE $3C,$2A,$54,$14,$28,$CF,$08,$10          .BYTE $FF,$3C,$08,$10,$14,$28,$CF,$28          .BYTE $14,$F3,$50,$0A,$1C,$A0,$05,$01          .BYTE $46,$62,$86,$80,$02,$88,$11,$40          .BYTE $61,$05,$10,$08,$A0,$11,$18,$E0          .BYTE $07,$88,$0F,$FF,$FF,$86,$F0,$0F          .BYTE $FF,$FF,$F0,$E1,$1F,$FF,$FF,$F8          .BYTE $FF,$FFproicon	  .BYTE $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF          .BYTE $FF,$00,$1F,$FF,$FF,$FF,$FF,$F8          .BYTE $3F,$FF,$F0,$FF,$FF,$FF,$FC,$FF          .BYTE $CC,$03,$7F,$01,$80,$CF,$03,$7F          .BYTE $FC,$01,$80,$00,$3F,$FF,$FF,$FF          .BYTE $FF,$FC,$1C,$FF,$60,$FF,$F3,$FF          .BYTE $38,$03,$0C,$FD,$C0,$FF,$FF,$FF          .BYTE $FF,$FF,$FFupper	  .BYTE $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF	        ;CHG024          .BYTE $FF,$2F,$08,$1F,$FF,$08,$FF,$FC          .BYTE $10,$1F,$FF,$FF,$FC,$02,$20,$1F          .BYTE $FF,$FF,$FC,$47,$F8,$20,$1F,$FF          .BYTE $FF,$FC,$80,$1F,$FF,$08,$FF,$FC          .BYTE $80,$1F,$FF,$FF,$FC,$80,$47,$F8          .BYTE $1F,$FF,$FF,$FC,$20,$E0,$1F,$FF          .BYTE $FF,$FC,$10,$FB,$08,$FF,$FF,$FF          .BYTE $FF,$FF,$FF,$FFdriven	  .BYTE $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF	        ;CHG024          .BYTE $FF,$EF,$02,$38,$03,$FF,$04,$07          .BYTE $FF,$22,$88,$3F,$FF,$F8,$11,$FE          .BYTE $E8,$7F,$FF,$FC,$20,$8B,$20,$7F          .BYTE $FF,$FC,$A0,$11,$FE,$3F,$FF,$F8          .BYTE $08,$E3,$07,$FF,$84,$F8,$03,$FF          .BYTE $02,$FF,$FF,$FF,$FF,$FF,$FF,$FFinsertd	  .BYTE $FF,$79,$07,$FE,$0F,$C6,$FF,$7F          .BYTE $FF,$F0,$71,$FF,$FF,$F8,$0A,$18          .BYTE $AA,$AA,$A8,$FA,$AA,$AA,$F6,$A0          .BYTE $60,$E3,$03,$C0,$07,$38,$04,$20          .BYTE $06,$08,$10,$FF,$F3,$08,$10,$3C          .BYTE $04,$20,$03,$C0,$FF,$FF,$FF,$FF          .BYTE $61,$1F,$FF,$FF,$F8,$0F,$38,$FF          .BYTE $FF,$F0,$01,$80,$CF,$02,$40,$F3          .BYTE $04,$20,$3C,$08,$10,$10,$08,$CF          .BYTE $1C,$38,$FF,$FF,$CF,$03,$C0keybdout  .BYTE $CF,$01,$C0,$FF,$3F,$0E,$38,$CF          .BYTE $08,$08,$F3,$04,$10,$3C,$02,$20          .BYTE $01,$40,$DF,$80,$F3,$01,$C0,$3F          .BYTE $01,$40,$20,$1B,$6D,$B6,$DB,$60          .BYTE $16,$DB,$08,$6D,$B6,$DF,$3B,$6D          .BYTE $B6,$DB,$80,$67,$80,$06,$DB,$6D          .BYTE $B6,$D8,$FF,$0F,$4F,$FF,$FF,$FF          .BYTE $00,$FF,$F0,$FF,$FF,$FF,$FF,$FF          .BYTE $F8,$00,$1B,$6D,$B6,$D8,$36,$C0          .BYTE $1B,$6D,$00,$B6,$D8,$36,$C0,$1B          .BYTE $6D,$B6,$D8,$00,$36,$C0,$1B,$6D          .BYTE $B6,$D8,$36,$C0,$00,$1B,$6D,$B6          .BYTE $D8,$36,$C0,$1B,$6D,$00,$B6,$D8          .BYTE $36,$C0,$1B,$FF,$FF,$D8,$00,$36          .BYTE $C0,$1B,$FF,$FF,$D8,$36,$C0,$00          .BYTE $FF,$FF,$FF,$FF,$FF,$F8,$7F,$FF          .BYTE $F0,$FF,$FF,$FF,$F0,$FFmouseout  .BYTE $FD,$E0,$FF,$F3,$07,$1C,$3C,$04          .BYTE $04,$02,$08,$CF,$01,$10,$F7,$A0          .BYTE $3D,$40,$01,$E0,$FF,$F3,$01,$20          .BYTE $7F,$3F,$9C,$FF,$80,$FF,$FE,$FF          .BYTE $FF,$3C,$7E,$7C,$FF,$FE,$CF,$1F          .BYTE $F0,$F3,$0F,$E0,$3C,$0F,$E0,$1F          .BYTE $F0,$FF,$FF,$FF,$FF,$FF,$FF,$CF          .BYTE $FF,$FEQuestion  .BYTE $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF          .BYTE $CF,$0F,$E0,$F3,$03,$80,$FE,$0C          .BYTE $CF,$03,$80,$F7,$E0,$BF,$03,$EF          .BYTE $03,$FF,$FE,$03,$FF,$FF,$FF,$FF          .BYTE $FF,$FF,$FFcheckmrk  .BYTE $CF,$07,$80,$F3,$0E,$80,$BE,$1B          .BYTE $36,$EF,$6C,$7B,$D8,$01,$9E,$B0          .BYTE $03,$60,$E7,$06,$C0,$79,$0D,$80          .BYTE $1B,$DF,$36,$F7,$6C,$3D,$D8,$01          .BYTE $B0,$CF,$03,$60,$F3,$06,$C0,$BC          .BYTE $0D,$80,$1B,$EF,$36,$FB,$6C,$9E          .BYTE $D8,$01,$B0,$E7,$03,$60,$38,$F8          .BYTE $06,$C0,$DC,$0D,$CE,$80,$36,$1B          .BYTE $F3,$1B,$36,$3C,$0D,$EC,$06,$D8          .BYTE $CF,$03,$30,$F3,$01,$E0badmrk	  .BYTE $3C,$03,$C0,$02,$E0,$CF,$01,$B0          .BYTE $F7,$D8,$7D,$6C,$36,$DF,$1B,$E7          .BYTE $0D,$80,$79,$06,$C0,$03,$9E,$60          .BYTE $01,$B0,$EF,$D8,$FB,$6C,$BE,$36          .BYTE $1B,$CF,$0D,$80,$F3,$06,$C0,$3C          .BYTE $03,$60,$01,$B0,$DF,$D8,$F7,$6C          .BYTE $7D,$36,$1B,$9F,$0D,$80,$E7,$06          .BYTE $C0,$79,$03,$60,$01,$BE,$B0,$D8          .BYTE $EF,$6C,$FB,$36,$3E,$1B,$0E,$80diskette  .BYTE $FF,$FF,$FF,$FF,$1F,$03,$FF,$FF          .BYTE $86,$F8,$07,$FF,$FF,$F4,$EF,$0A          .BYTE $FB,$05,$BC,$02,$80,$01,$FF,$7D          .BYTE $78,$84,$CF,$01,$02,$FF,$7C,$01          .BYTE $02,$84,$DF,$78,$FF,$FF,$FF,$7F          .BYTE $07,$10,$FF,$FF,$FF,$80,$03,$FF          .BYTE $FF,$FE,$FF,$FF,$FF,$FFlisa	  .BYTE $FF,$0F,$03,$FF,$FF,$FF,$00,$FF          .BYTE $C0,$07,$FF,$FF,$FF,$FF,$E0,$10          .BYTE $0C,$FF,$FF,$F0,$30,$01,$FF,$70          .BYTE $FF,$F8,$07,$80,$01,$9E,$FF,$01          .BYTE $FF,$CF,$07,$80,$FF,$3F,$07,$80          .BYTE $E7,$01,$FF,$09,$01,$FF,$01,$FF          .BYTE $FF,$F8,$40,$07,$80,$0C,$FF,$FF          .BYTE $F0,$30,$00,$07,$FF,$FF,$FF,$FF          .BYTE $E0,$03,$FF,$00,$FF,$FF,$FF,$C0          .BYTE $03,$FF,$FF,$FF,$00,$FF,$E0,$07          .BYTE $FF,$FF,$FF,$FF,$F0,$61,$AA,$AA          .BYTE $AA,$95,$FF,$18,$FF,$FF,$9F,$5F          .BYTE $FF,$FD,$86,$1F,$0A,$AA,$A8,$15          .BYTE $3F,$07,$FF,$00,$FF,$FF,$FF,$F0          .BYTE $03,$FF,$FF,$FF,$FC,$FF,$E0,$FF          .BYTE $FF,$FF        .ENDC        .PAGE        .LIST;----------------------------------------------------------------------;  Message Table;----------------------------------------------------------------------        .IF  USERINT = 0        .IF  ROM4K = 0INITMSG .ASCII  'SELF TEST OK'        .BYTE   0        .IF  ROM8K = 1        .IF  NEWTWIG = 0CROMMSG .ASCII  'CPU ROM 1.08'        .BYTE   0        .ENDC        .IF  NEWTWIG = 1CROMMSG .ASCII  'CPU ROM 1.18'        .BYTE   0        .ENDC        .ENDCIORMMSG .ASCII  'IO ROM '        .BYTE   0CPUMSG  .ASCII  'CPU LOGIC FAILURE'        .BYTE   0        .ENDC			        ;{ROM4K}RAMMSG  .ASCII  'MEMORY FAILURE'        .BYTE   0IOMSG   .ASCII  'IO LOGIC FAILURE'        .BYTE   0IOSMSG  .ASCII  'IO SLOT FAILURE'        .BYTE   0DSKMSG  .ASCII  'PLEASE INSERT DISK'        .BYTE   0BOOTERR .ASCII  'STARTUP FAILURE'        .BYTE   0DVCMSG  .ASCII  'DEVICE '        .BYTE   0ERRMSG  .ASCII  'ERROR '	        ;FOR ERROR CODE OUTPUT        .BYTE   0EXCPMSG .ASCII  'EXCEPTION'        .BYTE   0        .IF  ROM4K = 0BOOTMSG .ASCII  'BOOTING...'        .BYTE   0        .ELSEBOOTMSG .ASCII  'BOOTING'        .BYTE   0        .ENDCBADBOOT .ASCII  'INVALID SELECTION'        .BYTE   0        .ENDC			        ;{USERINT}        .IF     BURNIN = 1BRNMSG  .ASCII  'POWER CYCLING AT '        .BYTE   0TIMMSG  .ASCII  'TIME IS '			       ; RM000        .BYTE   0TWGMSG  .ASCII  'DRIVE TEST'			       ; RM000        .BYTE   0LOOPMSG .ASCII  'LOOP COUNT IS '        .BYTE   0PMMSG   .ASCII  'PM BUS ERROR'        .BYTE   0TWGFAIL .ASCII  'FLOPPY TEST FAILED'        .BYTE   0TWGRSLT .ASCII  'FLOPPY ERROR COUNT IS '        .BYTE   0        .ENDC        .IF  ROM4K = 0        .IF  USERINT = 0CONTMSG .ASCII  '2-CONTINUE  '        .BYTE 0LEV1MSG .ASCII  '1-RETRY  3-STARTUP FROM...  ?'        .BYTE   0LEV2MSG .ASCII  '1-DISPLAY  2-SET  3-CALL  '        .IF ROM16K = 1        .ASCII  '4-DUMP	 5-VERIFY  6-LOOP  '        .ENDC        .ASCII  '7-ADJUST VIDEO	 9-QUIT	 ?'        .BYTE   0        .ELSECHKMSG  .ASCII  'TESTING'        .BYTE   0        .ASCII  'TEST'		        ;French translation        .BYTE   0        .ASCII  'ES WIRD GETESTET'      ;German translation        .BYTE   0RTRYMSG .ASCII  'RESTART'        .BYTE   0        .ASCII  'RECOMMENCER'	        ;French        .BYTE   0        .ASCII  'NEU STARTEN'	        ;German        .BYTE   0CONTMSG .ASCII  'CONTINUE'        .BYTE   0        .ASCII  'CONTINUER'	        ;French        .BYTE   0        .ASCII  'WEITERMACHEN'	        ;German        .BYTE   0STRTMSG .ASCII  'STARTUP FROM'        .BYTE   0        .ASCII  'DEMARRER DE'	        ;French        .BYTE   0        .ASCII  'STARTEN VON'	        ;German        .BYTE   0PERIODS .ASCII  '...'        .BYTE   0MENUHDG .ASCII  'OPTIONS'        .BYTE   0DISPMSG .ASCII  'DISPLAY MEM   1'        .BYTE   0SETMSG  .ASCII  'SET MEMORY    2'        .BYTE   0CALLMSG .ASCII  'CALL PROGRAM  3'        .BYTE   0        .IF  ROM16K = 1LPMSG   .ASCII  'LOOP ON TEST  4'        .BYTE   0        .ENDCVIDMSG  .ASCII  'ADJUST VIDEO  5'        .BYTE   0        .IF  BURNIN = 1CYCLMSG .ASCII  'POWER CYCLE   6'        .BYTE   0        .ENDCQUITMSG .ASCII  'QUIT	       7'        .BYTE   0MENUID  .BYTE   KEY1,KEY2,KEY3		        ;menu id table        .IF  ROM16K = 1        .BYTE   KEY4        .ENDC        .BYTE   KEY5        .IF  BURNIN = 1        .BYTE   KEY6        .ENDC        .BYTE   KEY7        .ENDC        .IF  ROM16K = 1        .IF  FULLSCC = 0NOTAMSG .ASCII  'NOT YET AVAILABLE'        .BYTE   0        .ENDCTSTMENU .ASCII  '1 - ROM'        .BYTE   RET        .ASCII  '2 - MMU'        .BYTE   RET        .ASCII  '3 - VIDEO'		        ;RM000        .BYTE   RET        .ASCII  '4 - PARITY'		        ;RM000        .BYTE   RET        .ASCII  '5 - PARA VIA'		        ;RM000        .BYTE   RET        .ASCII  '6 - KYBD VIA'		        ;RM000        .BYTE   RET        .ASCII  '7 - COPS'        .BYTE   RET        .ASCII  '8 - SCC'        .BYTE   RET        .ASCII  '9 - DISK'        .BYTE   RET        .ASCII  'A - CLOCK'        .BYTE   RET        .ASCII  'B - MEMORY'        .BYTE   RET        .ASCII  'C - IO SLOTS'        .BYTE   0        .ENDC        .IF  USERINT = 0ADDRMSG .ASCII  'ADDRESS?>'        .BYTE   0DATAMSG .ASCII  'DATA ?	 >'        .BYTE   0CNTMSG  .ASCII  'COUNT ? >'        .BYTE   0DRVMSG  .ASCII  'DRIVE ? >'        .BYTE   0DVCEMSG .ASCII  'DEVICE ?>'        .BYTE   0TSTMSG  .ASCII  'TEST  ? >'        .BYTE   0        .ELSEADDRMSG .ASCII  'ADDRESS ?'        .BYTE   0DATAMSG .ASCII  'DATA ?'        .BYTE   0CNTMSG  .ASCII  'COUNT ?'        .BYTE   0TSTMSG  .ASCII  'TEST ?'        .BYTE   0        .ENDCWHATMSG .ASCII  'WHAT ?'        .BYTE   0        .ENDC			        ;{ROM4K}        .IF  ROM4K = 1        .ORG    $0FFCVRSN    .WORD   $0027	        ;version 0.27        .ENDC        .IF  ROM8K = 1        .ORG    $1FFC        .IF  NEWTWIG = 0VRSN    .WORD   $0108	        ;version 1.08        .ENDC        .IF  NEWTWIG = 1VRSN    .WORD   $0118	        ;version 1.18        .ENDC        .ENDC        .IF  ROM16K = 1        .ORG    $3FF4	        ;			        CHG005;************ COPYRIGHT NOTICE ***************************************HDGMSG  .ASCII  'C84APPLE'      ;			        CHG005;*********************************************************************VRSN    .BYTE   $02	        ;version 2		        CHG001REV     .ASCII  'H'	        ; rev H			        CHG001        .ENDCLAST    .WORD   $0000	        ;checksum word for ROM test        .END