TweetFollow Us on Twitter

Application List
Volume Number:1
Issue Number:7
Column Tag:standard file

Available Application List

By Chris Yerga

A few weeks ago I was compiling a disk of my favorite games for a friend of mine. Disk space being as valuable as it is, the Finder’s use of close to 50K of disk space seemed a terrible waste on a disk containing files that would probably never be manipulated in any way. Armed with my copy of Inside Macintosh, I set out to correct this injustice. My goal was to write a short program that would present the user with a list of the available applications and allow him to execute the one of his choosing. As is usually the case when I set out to write a program, I found that what seems at first to be an arduous task (up to this point I had never tried to access the disk drive and the file directory) is actually quite simple when full advantage is taken of the Mac’s built in routines. This article will concern itself with two such routines: the Standard File routine and the Launch facility.

Working according to the flow of the program, our first concern is to list the available applications and allow the user to select the one he wants to execute. Anyone who has ever opened a document from an application should be familiar with the Standard Get File dialog box [See BASIC column for an introduction to Standard File dialog box]. This standard method of opening a file is quite simple to implement through the convenience of the Package Manager. The package manager allows an application to call one of several “packages” -- short specialized routines kept in the System file -- from its main code. This saves the programmer from having to write code to perform the tasks that are provided for by the Package Manager. There are packages for opening files, saving files, initializing disks, and performing Binary/Hex conversion among others.

The package that we are going to use is called the Standard Get File package. It lists all the files of a certain filetype that are on a disk and allows the user to choose one of them. As programmers, virtually all that we are required to do is tell the package manager what filetype(s) that we want listed and where to put the resulting information. The PM takes care of the rest: it creates the dialog box, reads the disk directory, handles events, and stores the input that it gets from the user. This is exactly what we want, so our task is simplified immensely by this routine. However, if we did need the PM to function a bit differently, it has provisions for designing custom dialog boxes and performing special event handling tasks.

Page 13 of the Package Manager Programmer’s Guide portion of Inside Macintosh describes the standard get file procedure’s PASCAL interface as follows:

Procedure SFGetFile  (where: Point;  prompt: Str255;  fileFilter:  ProcPtr; 
 numTypes: INTEGER;  typeList:  SFListPtr; dlgHook: ProcPtr;  VAR reply: 
SFReply);

From assembly language, the first value that we need to push is where, which describes the top lefthand point at which the dialog box will be drawn. A bit of experimentation convinced me that (80,86) would serve our purpose well. The next variable, prompt, is not used by the current PM; however, older versions did require it to be passed, and so the PM accepts it to insure compatability with older programs. FileFilter is used by applications that want to determine for themselves which files to display in the dialog box. We will pass NIL for this variable, because we would rather have the PM do it for us. NumTypes tells the PM how many different filetypes we want displayed. In our case this value is 1, since we only want applications displayed. Next, we push typeList, a pointer to the list of filetypes to be displayed. DlgHook is used by applications that need to draw a custom dialog box. Again, since the standard dialog box suits our needs, we will pass NIL. Finally, VAR SFReply points to the standard file reply record, a data structure through which the PM communicates with the calling application. The assembly language implementation looks like this:

SFGetFile From Assembly

MOVE.W  #86,-(SP);Y coord. of where
MOVE.W  #80,-(SP);X coord. of where
PEA‘Prompt’ ;prompt: unused, but 
 ;we need to pass a  ;string to keep the 
 ;Package Manager  ;happy
CLR.L -(SP) ;fileFilter:  unused,  
 ;so we pass NIL
MOVE.W  #1,-(SP) ;numTypes:  there is 
 ;only 1 filetype in 
 ;our list
PEATypeList ;typeList:  points to 
 ;our list of filetypes
CLR.L -(SP) ;dlgHook:  unused,  so 
 ;we pass NIL
PEASFReply;SFReply:  points to 
 ;the Reply Record

The reply record contains information such as the filename, filetype, the volume where the file can be found, etc. Its structure, as described in Inside Macintosh is shown in figure 1.

The first variable, good, tells whether or not valid data is in the reply record. If it is FALSE, then the user hit the cancel button or for some other reason, the data should be ignored. If TRUE, then the call was successful and the calling application can process the data. Copy is unused; Inside Macintosh gives no explaination. The next variable is fType, the 4 character filetype of the file selected. We do not need to look at this, because it will always be ‘APPL’ -- the filetype for applications. VRefNum is the volume reference number of the volume that contains the selected file. This is needed in many file manager calls. Version is the version number of the selected file. Perhaps the most useful piece of information is fName, the filename of the selected file.

After everything has been set up, we are ready to invoke the standard get file package as follows:

MOVE.W  #2,-(SP) ;Call SFGetFile through 
_Pack3  ;the package manager

After checking good and determining that a successful call has occurred, the only remaining task is running the selected application.

The routine responsible for running an application is located in the Segment Loader and is called Launch. The launch routine is unique in the method used to call it. Unlike the toolbox traps, in which values are passed on the stack, launch is a routine whose values must be pointed to by an address register. Register based routines such as this are common in the low level system portion of the Macintosh ROM.

In calling the launch routine, the programmer passes a pointer to the Launch Pointer Record in A0 [Fig 2]. The first 4 bytes of the LP record (no pun intended...) consist of a pointer to the filename of the application we want to run. As all Macintosh programmers must quickly learn, the assembly language equivalent of a pointer is an Effective Address. In order to get a pointer to the filename, we load its effective address into address register A1 by the instruction LEA FileName,A1. When we have the effective address (or pointer) in a register, we are free to store it in the proper location of the LP record. The last 2 bytes compose a word of data that tells the launch routine how we want memory allocated to the application. A value of NIL in this location gives standard memory allocation (as the Finder would), so we do not need to change it.

After the LP record has been set up and A0 is pointing to it, the trap _Launch is called and we are finished.

The balance of the program consists of initialization calls to the various managers and a few QuickDraw traps to display the title of the program. The program as I have implemented it is functional, but rather spartan in its lack of features and appearance. No resources were included and there is no use of menus or windows. The purpose of this article was to describe some interesting parts of the toolbox, not to reiterate the material that David has described in his column. However, I encourage you to liven your own versions up by putting some graphics or a description of the program somewhere on the screen. At least put your name in it and impress your friends!

;    MicroFinder      
;   
;     A startup program that allows   
;  the user to select the  
;     the application that he wants 
;  to run of those on the disk.     
;  June 1985.     
;   
;    © MacTutor by Chris Yerga        
;      Contributing Editor            

;     ToolBox & System Traps        

.TRAP   _InitCursor$A850
.TRAP   _InitGraf$A86E
.TRAP   _SetPort $A873
.TRAP   _BackPat $A87C
.TRAP   _DrawString$A884
.TRAP   _TextFont$A887
.TRAP   _TextSize$A88A
.TRAP   _MoveTo  $A893
.TRAP   _PenPat  $A89D
.TRAP   _FrameRect $A8A1
.TRAP   _PaintRect $A8A2
.TRAP   _EraseRect $A8A3
.TRAP   _InitFonts $A8FE
.TRAP   _GetWMgrPort $A910
.TRAP   _InitWindows $A912
.TRAP   _InitMenus $A930
.TRAP   _InitDialogs $A97B
.TRAP   _TEInit  $A9CC
.TRAP   _FlushEvents $A050
.TRAP   _InitPack$A9E5
.TRAP   _Pack3   $A9EA
.TRAP   _Launch  $A9F2

;    Declaration of external labels     

XDEF  START ;For the  linker

;        Local Constants     

AllEvents equ  $0000FFFF
Athens  equ 7    ;Our text values
AthenSize equ  18

;      Start of Main Program   

START:

MOVEM.L D0-D7/A0-A6,-(SP) 
LEASAVEREGS,A0
MOVE.L  A6,(A0)
MOVE.L  A7,4(A0)
 
;      Initialize the ROM routines  

 PEA  -4(A5);QD Global ptr
 _InitGraf;Init QD global
 _InitFonts ;Init font manager
 _InitWindows  ;Init Window Mgr
 _InitMenus ;Init menu manager 

 CLR.L  -(SP)  ;Get standard  ;failsafe procedure 
 _InitDialogs    ;Init Dialog Manger
 _TEInit;Init Text edit for ;the heck of it
 
 MOVE.W #2,-(SP)
 _InitPack;Init Package Mgr
 
 MOVE.L #AllEvents,D0;And flush 
 _FlushEvents    ;events
 _InitCursor;Get the arrow
 
;       Start of the Main Code      

PEAGptr ;Get Handle to WMgrPort
_GetWmgrPort

LEAGptr,A0
MOVE.L  (A0),-(SP) ;Push address of  ;the ptr to the port
_SetPort;And open the port
 
PEAGrayPat;Set the Backround  ;Pat’rn to 50% Gray
_BackPat
PEAScreen ;And clear the screen
_EraseRect
 
;  Display the Title of the program   

 
PEAWhitePat ;white rectangle text
_PenPat ;Set the pattern to white
PEATitleRect;Point to our rectangle
_PaintRect;and fill it with the Pen Pat.
PEABlackPat ;draw a thin Black border
_PenPat ;Set the pattern to black
PEATitleRect;Point to our rectangle 
_FrameRect;and draw the frame of it

MOVE.W  #135,-(SP) ;position Pen 
MOVE.W  #60,-(SP);Screen (60,135)
_MoveTo ;Position pen...
MOVE.W  #Athens,-(SP);Choose font 
_TextFont ;(Athens = 7)
MOVE.W  #AthenSize,-(SP) ;size of text
_TextSize ;(AthenSize = 18)

PEA‘LaunchAp 1.0 by Chris Yerga’ 
_DrawString ;And draw it... 
PEAWhitePat ;Background Pat. to  white
_BackPat;So the dialog box looks   ;normal...
 
 
MainLoop: 
 
;        SFGETFILE ROUTINE   

MOVE.W  #86,-(SP);Y Coordinate
MOVE.W  #80,-(SP);X Coordinate
PEA‘PROMPT’ ;Prompt (Unused)
CLR.L -(SP) ;NIL for FileFilter
MOVE.W  #1,-(SP) ;We only want 1 file  ;type listed
PEATypeList ;Point to the Type     ;List
CLR.L -(SP) ;NIL for dlgHook
PEASFReply;Point to the Reply ;Record
MOVE.W  #2,-(SP) ;Routine Selector ;for SFGetFile
_Pack3  
LEASFReply,A0    ;Get the result   ;from the Package           
 ;Manager
CMP.B #0,(A0)    ;was it successful  ;(good = TRUE) ?
BEQMainLoop ;Nope, user hit the    ;cancel button, try
 ;again till he  ;figures it out 
PEABlackPat ;Clear the screen ;to Black
_PenPat
PEAScreen
_PaintRect
 
;       Launch Routine     

LEASFileName,A1  ;Get the address of ;the filename
LEALaunchPtr,A0  ;Get the address of ;the Launch Ptr in
 ;A0 (according to ;Register Based 
 ;conventions.
MOVE.L  A1,(A0)  ;Move the Ptr to the  ;address of the 
 ;filename (in A1) ;to the first word  ;of the Launch Ptr
_Launch ;And call Launch  ;...zoom!

;   
;      The Program’s Variables       
;   

SAVEREGS: DCB.L  2,0

GPTR:   DS.L1  ;Space for ;the GrafPtr
SCREEN: DC.W0,0,342,512   
 ;Rectangle describing the full
 ;Macintosh screen
TITLERECT:DC.W 41,127,69,381;Rectangle that contains the name
 ;of the program etc.
 
TYPELIST:  DC.L ‘APPL’  ;The list of file                      
 ;types we want
 ;displayed in the ;Standard File
 ;dialog box. In this     ;case, there is
 ;only 1 type

;                  
;      The Standard File Reply Record ;                 

SFREPLY:DC.B0,0  ;good, copy  (BOOLEAN)
 DC.B ‘TYPE’;fType (OSType)
 DC.W 0,0 ;vRefNum,version(INT)
SFILENAME:DCB.B  63,0;fName  (STRING[63])

;     The Launch Pointer Record     

LAUNCHPTR:DC.L 0 ;Ptr to the  ;FileName
 DC.W 0 ;Mode (0 = ;standard  ;memory
 ;allocation)

;       Pattern Definitions  

GRAYPAT:    DC.B  $55, $AA, $55, $AA, $55, $AA, $55, $AA
BLACKPAT:  DC.B  $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
WHITEPAT:  DC.B    0,0,0,0,0,0,0,0
 
;End of Program Source Code

MicroFinder Bug Fix

Shawn Mikiten

San Antonio, Tx.

MicroFinder [June MacTutor 1-7] works well as long as you do not select a file on the other disk drive. The bug appears in the way the _Launch trap runs the application. The filename is properly passed but not the volumne the file is on. The _Launch trap will automatically attempt to run the application on the disk the MicroFinder was started from because the filename did not have the volumne specifier before it. The solution lies in the _Pack3 reply record. The variable vRefNum contains the disk drive number of the file when it returns from a successful call. Using the vRefNum value obtained, it is put in a parameter block for the File Manager call _SetVol. The parameter used is ioDrvNum. The following are directions for patching the source code so that it will work (See File Manager /OS/FS.A.1, page 26 & 33 in the new “Inside Macintosh” phone book.)

Add _SetVol trap value:

.TRAP      _SetVol               $A015

The code following _PaintRect is to be added:

_PaintRect

;   Launch Routine here

LEA          PARMBLK, A0         ;get pointer
LEA           vRefNum, A1           ; get addr. of vRefNum
MOVE.W   (A1), 22(A0)           ; put vRefNum into the
                                                               ; ioDrvNum 
parameter.
_SetVol                                            ; set it. (note A0 
points to
                                                             ; the param. 
block!)

LEA        SFileName, A1          ; get addr. of filename

Next, add the data structures necessary for the Reply record and parameter block. Add vRefNum in the Reply record:

SFREPLY:         DC.B      0,0           ; good, copy 
                              DC.B      ‘TYPE’    ; FType     (ostype)
 vRefNum:         DC.W       0,0          ;  vRefNum, version 
SFILENAME:   DCB.B    63,0       ; fname (string[63]) 

And now the parameter block, to be added after the WHITEPAT definition (Note that the file name pointer must be nil to force invocation of vRefNum inserted into ioDrvNum.):

;  standard 8 field parameter block for setvol.

PARMBLK:           DC.L       0            ;ioLink ptr.
                                     DC.W      0           ; ioType
                                     DC.W      0           ; ioTrap
                                     DC.W      0          ; ioCmdAddr
                                    DC.L         0          ; ioCompletion 
ptr.
                                    DC.W        0          ; ioResult
                                    DC.L          0          ; ioFileName 
ptr.
                                    DC.W        0          ; ioDrvNum

I hope this bug fix will offset the cost of the MDS software I am about to purchase. I havebeen using a friends copy and find it the easiest assembler I have used in 7 years of Apple II’s, Digital 2065, IBM PC and VAX computers!

[Shawn wins the $50 for being first with his bug fix. Thank you to the four other people who submitted a fix: Loftus Becker Jr. of Hartford, CT, who submitted a similar solution to Shawn’s; Tom Taylor of Provo Utah and Neal Lebedin of Palm Bay, FL., both of whom submitted similar solutions but slightly different from Shawn’s; And Paul Snively of Columbus, IN. in MacAsm...-Ed.]

More Bug Fix Comments

Loftus E. Becker, Jr.

Hartford, CT.

The bug in Chris Yerga’s microfinder program (ID=26) is “failure to launch”. This stems from the fact that the lanuch routine will look for the named file on the default volume unless it is told otherwise. Hence, when the microfinder program is run from the default volume (usually drive 1) and tries to launch a program on drive 2, Launch gets the filename, doesn’t know it’s on drive 2, and tries to launch from drive 1!

Two points may be of some interest. First this is a bomb that is not trapped by Macsbug. Second, a similar bug appears in the MDS development system: If you are developing a program with the .asm, .link, and other files on the external drive, but the program itsef on the internal drive, an attempt to run it from the TRANSFER menu in the linker will produce the same error.My compliments on a magzine that has gotten better with every issue.

Alternate Bug Fix

Tom Taylor

Provo, UT

This is similar in function , but uses the stack for the parameter block...

ioVQElSize         EQU   $40     ;io param blk length
ioCompletion       EQU   $C       ;offset (ptr.)
ioVNPtr            EQU   $12     ;offset (ptr. or nil)
ioVRefNum          EQU   $16     ;offset (word)

SUB.L    #ioVQElSize, SP    ;allocate block on stack
MOVE.L  SP, A0                        ;block ptr. to A0
CLR.L     ioCompletion(A0)  ; I always clear this
LEA         SFReply, A1             ; reply record ptr to A0
MOVE.W 6(A1), ioVRefNum(A0)  
CLR.L      ioVNPtr(A0)             ;clear name ptr.

_SetVol                                           ; go for it...
ADD.L      #ioVQElSize, SP  ; dump block

MacAsm Version of Bug Fix

Paul Snively

Columbus, IN

Apparently the standard file package, even though it automatically senses the presence of a second disk drive and, if one is present, gives you the “Drive” button in the standard dialog box, does not automatically change the default volume if the “Drive” button is hit. Where I come from, features like this are called “bugs.” In other words, as far as I’m concerned, the bug is in the standard file package, not Chris’ code

.
01150 *--------------------------------
01160 *        Launch Routine (MacAsm)
01170 *--------------------------------
01180          LEA     ParamBlock(PC),A0 ;File Man. param Blk
01190          LEA     vRefNum(PC),A1       ;Volume Ref Number
01200          MOVE.W  (A1),22(A0)           ;Move to paramBlock
01210          OST     SetVol                  ;Make the default volume
01220          LEA     SFileName(PC),A1   ;Get addr of file name
01230          LEA     LaunchPtr(PC),A0    ;Get addr of launch ptr
01240          MOVE.L  A1,(A0)                    ;Move pointer to name
01250          TBX     Launch                         ;And call Launch...
 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Capto 1.2.9 - $29.99
Capto (was Voila) is an easy-to-use app that takes capturing, recording, video and image editing to the next level. With an intelligent file manager and quick sharing options, Capto is perfect for... Read more
Opera 51.0.2830.40 - High-performance We...
Opera is a fast and secure browser trusted by millions of users. With the intuitive interface, Speed Dial and visual bookmarks for organizing favorite sites, news feature with fresh, relevant content... Read more
GarageSale 7.0.13 - Create outstanding e...
GarageSale is a slick, full-featured client application for the eBay online auction system. Create and manage your auctions with ease. With GarageSale, you can create, edit, track, and manage... Read more
1Password 6.8.7 - Powerful password mana...
1Password is a password manager that uniquely brings you both security and convenience. It is the only program that provides anti-phishing protection and goes beyond password management by adding Web... Read more
Evernote 7.0.1 - Create searchable notes...
Evernote allows you to easily capture information in any environment using whatever device or platform you find most convenient, and makes this information accessible and searchable at anytime, from... Read more
MacUpdate Desktop 6.2.0 - $20.00
MacUpdate Desktop brings seamless 1-click app installs and version updates to your Mac. With a free MacUpdate account and MacUpdate Desktop 6, Mac users can now install almost any Mac app on... Read more
HoudahSpot 4.3.5 - Advanced file-search...
HoudahSpot is a versatile desktop search tool. Use HoudahSpot to locate hard-to-find files and keep frequently used files within reach. HoudahSpot will immediately feel familiar. It works just the... Read more
EtreCheck 4.0.4 - For troubleshooting yo...
EtreCheck is an app that displays the important details of your system configuration and allow you to copy that information to the Clipboard. It is meant to be used with Apple Support Communities to... Read more
WhatsApp 0.2.8361 - Desktop client for W...
WhatsApp is the desktop client for WhatsApp Messenger, a cross-platform mobile messaging app which allows you to exchange messages without having to pay for SMS. WhatsApp Messenger is available for... Read more
iClock 4.2 - Customize your menubar cloc...
iClock is a menu-bar replacement for Apple's default clock but with 100x features. Have your Apple or Google calendar in the menubar. Have the day, date, and time in different fonts and colors in the... Read more

Latest Forum Discussions

See All

The best games like Florence
Florence is a great little game about relationships that we absolutely adored. The only problem with it is it's over a little too soon. If you want some other games with some emotional range like Florence, check out these suggestions: [Read more] | Read more »
Angry Birds Champions adds cash prizes t...
Collaborating with developer Rovio Entertainment, GSN Games has released a twist on the Angry Birds formula. Angry Birds Champions features the same bird-flinging gameplay, but now you can catapult Red and co for cash. | Read more »
Around the Empire: What have you missed...
148Apps is part of a family. A big family of sites that make sure you're always up to date with all the portable gaming news. Just like a real family, I guess. I don't know, my mum never told me anything about Candy Crush to be fair. [Read more] | Read more »
The Battle of Polytopia Guide - Tips for...
The addition of multiplayer to The Battle of Polytopia has catapulted the game from a fun enough time waster to a fully-fledged 4X experience on your phone. We've been playing quite a few matches over the past week or so, and we've put together a... | Read more »
All the best games on sale for iPhone an...
Hi there, and welcome to our round up of all the best games that are on sale for iOS at the moment. It's not a vintage week in terms of numbers, but I'm pretty sure that every single one of these is worth picking up if you haven't already played... | Read more »
Disc Drivin' 2 Guide - Tips for the...
We're all still playing quite a bit of Disc Drivin' 2 over here at 148Apps, and we've gotten pretty good at it. Now that we've spent some more time with the game and unlocked more powerups, check out some of these more advanced tips: | Read more »
Alto's Odyssey Guide - How to Tackl...
Alto’s Odyssey is a completely stunning and serene runner, but it can also be a bit tricky. Check out these to try and keep your cool while playing this endless runner: Don’t focus too much on tasks [Read more] | Read more »
Here's everything you need to know...
Alto's Odyssey is a really, really good game. If you don't believe me, you should definitely check out our review by clicking this link right here. It takes the ideas from the original Alto's Adventure, then subtly builds on them, creating... | Read more »
Alto's Odyssey (Games)
Alto's Odyssey 1.0.1 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0.1 (iTunes) Description: Just beyond the horizon sits a majestic desert, vast and unexplored. Join Alto and his friends and set off on an endless... | Read more »
Vainglory 5v5: Everything you need to kn...
Vainglory just got bigger. [Read more] | Read more »

Price Scanner via MacPrices.net

Use your Apple Education discount and save up...
Purchase a new Mac using Apple’s Education discount, and take up to $400 off MSRP. All teachers, students, and staff of any educational institution with a .edu email address qualify for the discount... Read more
Apple Canada offers 2017 21″ and 27″ iMacs fo...
 Canadian shoppers can save up to $470 on the purchase of a 2017 current-generation 21″ or 27″ iMac with Certified Refurbished models at Apple Canada. Apple’s refurbished prices are the lowest... Read more
9″ iPads available online at Walmart for $50...
Walmart has 9.7″ Apple iPads on sale for $50 off MSRP for a limited time. Sale prices are for online orders only, in-store prices may vary: – 9″ 32GB iPad: $279.99 $50 off – 9″ 128GB iPad: $379.99 $... Read more
15″ Apple MacBook Pros, Certified Refurbished...
Save $360-$420 on the purchase of a 2017 15″ MacBook Pro with Certified Refurbished models at Apple. Apple’s refurbished prices are the lowest available for each model from any reseller. An standard... Read more
Amazon restocks MacBook Pros with models avai...
Amazon has restocked 15″ and 13″ Apple MacBook Pros with models on sale for up to $251 off MSRP. Shipping is free. Note that stock of some Macs may come and go (and some sell out quickly), so check... Read more
Lowest price of the year: 15″ 2.8GHz Apple Ma...
Amazon has the 2017 Space Gray 15″ 2.8GHz MacBook Pro on sale today for $251 off MSRP. Shipping is free: – 15″ 2.8GHz Touch Bar MacBook Pro Space Gray (MPTR2LL/A): $2148, $251 off MSRP Their price is... Read more
Apple restocks full line of Certified Refurbi...
Apple has restocked a full line of Apple Certified Refurbished 2017 13″ MacBook Pros for $200-$300 off MSRP. A standard Apple one-year warranty is included with each MacBook, and shipping is free.... Read more
Lowest sale price available for 13″ 1.8GHz Ma...
Focus Camera has the 2017 13″ 1.8GHz/128GB Apple MacBook Air on sale today for $829 including free shipping. Their price is $170 off MSRP, and it’s the lowest price available for a current 13″... Read more
21-inch 2.3GHz iMac on sale for $999, $100 of...
B&H Photo has the 2017 21″ 2.3GHz iMac (MMQA2LL/A) in stock and on sale for $999 including free shipping plus NY & NJ tax only. Their price is $100 off MSRP. Read more
Apple refurbished Mac minis in stock again st...
Apple has restocked Certified Refurbished Mac minis starting at $419. Apple’s one-year warranty is included with each mini, and shipping is free: – 1.4GHz Mac mini: $419 $80 off MSRP – 2.6GHz Mac... Read more

Jobs Board

*Apple* Retail - Multiple Positions - Apple,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Retail - Multiple Positions - Apple,...
Job Description:SalesSpecialist - Retail Customer Service and SalesTransform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Retail - Multiple Positions - Apple,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Solutions Consultant - Apple (United...
# Apple Solutions Consultant Job Number: 113523441 Orange, CA, California, United States Posted: 21-Feb-2018 Weekly Hours: 40.00 **Job Summary** Are you passionate Read more
*Apple* Retail - Multiple Positions - Apple,...
Job Description:SalesSpecialist - Retail Customer Service and SalesTransform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.