TweetFollow Us on Twitter

System Queues
Volume Number:5
Issue Number:1
Column Tag:Forth Forum

System Queues

By Jörg Langowski, MacTutor Editorial Board

Note: Source code files accompanying article are located on MacTech CD-ROM or source code disks.

“Looking at system queues”

The utility that I’m going to describe this month can be used to look at various queues of the Macintosh operating system. I was always curious to know what’s going on in the background of my machine while I’m working away; that’s how this example came to be. At the same time, the program contains another example of popup menus (for which the correct trap call has been added in Mach2.14), and how to use the userData field in the user variable area to display messages in a task window.

A number of queues are maintained by the Mac operating system; the example won’t list all of them, but some of the more important ones. Queues are linked lists of information blocks. Each block contains the address of the next list element in its first four bytes, a 16-bit number indicating the queue type in its next 2 bytes, and variable length information thereafter, as indicated below:

Fig.1: general structure of a Macintosh queue

The first element of a queue is called the queue header and the last one the queue tail. The queue tail has a link address of zero, meaning no more elements will follow. One can access the elements of a queue through a pointer to its header which is usually kept in a low memory global variable. For some of the queues the tail’s location is kept in another global variable for faster access.

The low memory addresses of the queues that our utility will display - vertical blanking queue, volume control block queue, drive queue, file system queue, event queue, deferred task queue and time manager queue - are defined at the beginning of the listing. (Since the address of the TM queue is not given in IM, I dug it out of a disassembly of the _InsTime trap.)

Structure of the program

We’ll set up a Mach 2 terminal task that contains the usual Apple, File and Edit menus (for desk accessories). The task window will contain a bar display for each queue which gives a visual indication of the size of the queue. The display bars are ‘click-sensitive’; when the mouse is clicked on one of them, a popup menu is displayed which shows the name of the queue. When this name is selected, a second window will be opened with information about the queue elements. That second window will disappear on a mouse click.

Inter-task communication in Mach2

I was happily hacking away on the example, got the rectangles drawn in the right places, the popup menus setup (note the slight difference in the interface that’s used here - built-in - from my code in MT V4#4), when I got a row of bad bombs trying to write text into a second window from the queue-monitoring task. Just ADDing a new window, then doing a _SetPort and using the Mach2 text I/O routines wouldn’t work at all. When it finally dawned on me what was I actually doing? The main task detects a mouse down in the content region of its window and calls the content handler (see listing) to find out which rectangle it has been clicked in, which menu to display, and to output the text in the second window. Now that is a totally trivial piece of code in a single task program like one would write in C or Pascal most of the time. In Mach2, things are different.

The mouse down event is not detected by the task that is supposed to handle it, but by the (in)famous I-O task, present in any Mach2 application. That task calls WaitNextEvent, detects which window the mouse was clicked in, and calls the event handler of the task that owns the window. So while we’re executing the event handler, we’re actually in the context of the I-O task! The standard Mach2 console output would be sent to the window associated with the I-O task. Unfortunately, there is no such window - therefore bomb.

The bottom line is that you can’t use the Forth text I-O routines from event handlers that are called through the I-O task. You have to rely on the means that Mach2 provides to do inter-task communication and make a terminal task do the text output.

Mach2 text output from event handlers

How is this achieved? The User area of a Mach2 task contains two locations, UserData and UserVector. When a non-zero value is stored in UserData, the routine pointed to by UserVector will be executed. So all we need to do is define a user vector handling routine, and have the content handler of the task store some message in UserData.

The content handler of our main window simply stores the menu ID of the selected popup menu in UserData. The user vector handler finds this menu ID (it gets passed on the stack), and calls the corresponding queue display routine.

The queue display routines use a second window, qInfo. In order to have the output appear in that window and not on top of our bar display, we have to change the task window pointer momentarily; this is done by storing the qInfo window pointer in the user variable taskWindowPointer, doing the output and later restoring the original pointer.

Queues displayed

The utility displays seven queues (and you can easily add more): vertical blanking, volume control block, drive, event, file system, deferred task, and time manager queues, in that order. The display bars are not labeled, but the popup menu will show you the name of the queue when you click on a bar.

When a popup menu has been selected, a queue list is displayed in a second window. The first two columns are the element number and queue type for each list element. The remaining columns vary according to the queue displayed. For the VBL queue, the VBL procedure pointer, the tick count and the ‘phase’ are listed. The VCB queue gives the name of each mounted volume, its drive number, driver and volume reference numbers, total number of allocation blocks, allocation block size and free blocks. The drive queue will give the drive number, driver reference number, file system ID, total number of blocks, and the status of the drive (locked disk, disk inserted, single or double sided for floppies). The status information is kept in the four bytes preceding the queue element (see IM II-128).

The event queue listing contains the what, message, when, where, and modifiers fields of the event. However, I’m sorry to say that in this case the listing window is next to useless, because the list is always empty when it is displayed. I’ll let you think of a reason why. The bar display sometimes shows queued events, when the display window is brought to the front from a partially covered position (its activate and update events).

Since I never found any pending asynchronous file system requests, I could not test the display for the FS queue, so that display routine is empty, just like the deferred task display. The time manager queue list shows the procedure pointer and count field for each time manager task.

In my system (MacII, 80MB hard disk, 5 MB memory, Appletalk and file server installed) I found a total of 8 VBL tasks, 2 time manager tasks, 2 mounted volumes (hard disk and Alisashare volume), and, interestingly, 5 different drives. I could make sense of three drives (SCSI disk, floppy drive and Alisashare disk), and can guess that a fourth ‘drive’, with the same file system ID as the Alisashare volume, might have something to do with the server. The fifth entry, with a queue type of 3, file system ID of $43C, and driver reference number of zero, doesn’t make sense to me. If someone has something to say about that point I’d be happier.

Why?

The crucial question - what is this utility good for? Besides satisfying the general curiosity of a system hacker, one important thing that I can imagine it would be helpful in is the detection of - you guessed it - viruses. At least background routines that install VBL or time manager tasks to do their malicious job might be spotted a lot easier when the queue display suddenly starts changing.

I did not add information about working directory control blocks, but you may do so if you like. The working directory queue header pointer is at $372.

Mach2 news

Finally, Palo Alto Shipping has published a trap compiler that allows you to add new traps to the Mach2 system without writing assembly code. The code is freely accessible on the Mach2 GEnie roundtable, but for those of you who don’t have access to GEnie, I’m including it on the source code disk together with some trap fixes for version 2.14. Sorry we can’t print the complete code here because it is too long; also you’ll have a lot of glue code typed in and debugged before you have finished typing the trap compiler in by hand. I’ll nevertheless print a short extract of the description:

This utility allows you to define your own trap “glue.” Thus as new system traps become available, you will be able to define their high-level interface symbolically (without using assembly language). It will also allow you to define a substitute syntax to the CALL interface, in case you need to modify (fix?) one of the existing traps. Note that in the latter case, you do not actually change the existing CALL, you simply define a new syntax which can be used in place of the CALL sequence.

One might wonder whether it makes good sense to include a 2K utility in an application when all you need is a few trap calls (but, see my comments below). However, for casual use you might consider putting this code in your workspace, along with your commonly used constants, mach words, and other compiler utilities (that way they will always be available during your “experimental” sessions). If you are working on a serious application, I would suggest the following approach. Place all variables, mach words, and compiler utilities (such as this trap compiler) in a separate segment and when you finish your application use ResEdit to remove that very same segment from your finished application.

This will work because mach words, variables, and compiler utilities (such as this trap compiler) do NOT need to be in memory during the execution of the code which they produce. Generally speaking, any word which only produces in-line code, most immediate words, or any child word which does not reference its parent at run-time can safely be removed from a finished application. If you are really concerned about making the smallest possible applications, then this is a technique which you should always use (as a final step, when you are completely finished with your program). If it seems risky to remove a segment from a finished application, just remember that there is NO WAY you can run code in another segment if that segment has NO jump-table entries (i.e. if you can’t get to the code, why include it in your application?)

Mach words, variables, and (most) compiler words don’t use or create jump-table entries. This same principle is why you never have to mark mach words or variables as GLOBAL (there is one exception, if you write a CODE word which explicitly states “JSR <mach word>” or “LEA <mach word>” then the defined instance of that <mach word> must be in memory at run-time. Thus if <mach word> exists in another segment, it will need to be marked GLOBAL (however, it’s always ok to say LEA <variable> or MOVE.L <variable>, thus variables “never” need to be marked as GLOBAL).

Waymen @ PASC

Thanks for that utility and the comments on segmentation.

Till next month.

Listing 1: System queue display

\ mini task to display system queues
\ © 1988 J. Langowski / MacTutor

only forth also assembler also mac

$160 constant vblqhdr
$356 constant vcbqhdr
$308 constant drvqhdr
$14a constant evtqhdr
$360 constant fsqhdr
$d92 constant dtqhdr
$b30 constant timevars
$11c constant utablebase

 72 user taskwindowpointer
 92 user (type)
108 user taskmenubar
144 user uservector
148 user userdata
152 user content-hook
164 user goaway-hook
168 user update-hook
172 user activate-hook

 2 CONSTANT Message
10 CONSTANT Where
14 CONSTANT Modifiers
 1 CONSTANT ActivateMask

300 constant appleid
301 constant fileid
302 constant editid

152 CONSTANT WrefCon

create rect1 20 w, 20 w, 90 w, 28 w,
create rect2 20 w, 35 w, 90 w, 43 w,
create rect3 20 w, 50 w, 90 w, 58 w,
create rect4 20 w, 65 w, 90 w, 73 w,
create rect5 20 w, 80 w, 90 w, 88 w,
create rect6 20 w, 95 w, 90 w, 103 w,
create rect7 20 w, 110 w, 90 w, 118 w,

CREATE APPLESTRING  01 C,  $14 C, 

NEW.MBAR queueBar

NEW.MENU AppleMenu
APPLESTRING AppleMenu TITLE
0 APPLEID AppleMenu BOUNDS
“ About Queues ...;(-” AppleMenu ITEMS

NEW.MENU FileMenu
“ File” FileMenu TITLE
0 FileID FileMenu BOUNDS
“ Quit” FileMenu ITEMS

NEW.MENU EditMenu
“ Edit” EditMenu TITLE
0 EDITID EditMenu BOUNDS
“ (Undo/Z;(-;(Cut/K;(Copy/C;(Paste/V;(Clear” EditMenu ITEMS

NEW.MENU vblmenu
“ vbl” vblmenu TITLE
-1 150 vblmenu BOUNDS
“ VBL Tasks;(-” vblmenu ITEMS

NEW.MENU vcbmenu
“ vcb” vcbmenu TITLE
-1 151 vcbmenu BOUNDS
“ Vol contrl blks;(-” vcbmenu ITEMS

NEW.MENU drvmenu
“ drv” drvmenu TITLE
-1 152 drvmenu BOUNDS
“ Drives;(-” drvmenu ITEMS

NEW.MENU evtmenu
“ evt” evtmenu TITLE
-1 153 evtmenu BOUNDS
“ Events [???];(-” evtmenu ITEMS

NEW.MENU fsmenu
“ fs” fsmenu TITLE
-1 154 fsmenu BOUNDS
“ File System;(-” fsmenu ITEMS

NEW.MENU dtmenu
“ dt” dtmenu TITLE
-1 155 dtmenu BOUNDS
“ Def Tasks;(-” dtmenu ITEMS

NEW.MENU tmmenu
“ tm” tmmenu TITLE
-1 156 tmmenu BOUNDS
“ Time manager;(-” tmmenu ITEMS

NEW.WINDOW SysQueue
“ System Queues” SysQueue TITLE
250 50 350 250 SysQueue BOUNDS
Rounded Visible CloseBox GrowBox SysQueue ITEMS

NEW.WINDOW qInfo
“ Queue Info” qInfo TITLE
50 50 250 500 qInfo BOUNDS
NoGrow Invisible NoCloseBox NoGrowBox qInfo ITEMS

500 2000 terminal queues

CODE unpack
 MOVE.L (A6),D0
 CLR.L   D1
 MOVE.W D0,D1
 CLR.W  D0
 SWAP.W D0
 MOVE.L D0,(A6)
 MOVE.L D1,-(A6)
 RTS
END-CODE MACH

: beep ( n )
 0 do 1 call sysbeep loop 
;

: wait { #ticks | time -- }
 call tickcount #ticks + -> time
 begin pause
 call tickcount time > 
 until
;

: popup.select { menu pt | point -- menuID item# }
 pt -> point 
 ^ point call localtoglobal 
 menu @ point unpack 1
 call popupmenuselect
 unpack
;

: do.content  {  | pt --  }
 CALL FrontWindow CALL SetPort
 qInfo call HideWindow
 
 RUN-CONTENT
 EVENT-RECORD Where + @ -> pt
 ^ pt CALL GlobalToLocal

 0
 pt rect1 CALL PtInRect
 IF drop vblmenu THEN
 pt rect2 CALL PtInRect
 IF drop vcbmenu THEN
 pt rect3 CALL PtInRect
 IF drop drvmenu THEN
 pt rect4 CALL PtInRect
 IF drop evtmenu THEN
 pt rect5 CALL PtInRect
 IF drop  fsmenu THEN
 pt rect6 CALL PtInRect
 IF drop  dtmenu THEN
 pt rect7 CALL PtInRect
 IF drop  tmmenu THEN
 
 ?dup IF ( rectangle was selected)
 pt popup.select 

 IF   ( popup selection was made )
 ( menuID ) userData task-> queues !
 THEN
 THEN
;
 
: draw.rects
 rect1 call framerect
 rect2 call framerect
 rect3 call framerect
 rect4 call framerect
 rect5 call framerect
 rect6 call framerect
 rect7 call framerect
;

: clr.rects
 rect1 call eraserect
 rect2 call eraserect
 rect3 call eraserect
 rect4 call eraserect
 rect5 call eraserect
 rect6 call eraserect
 rect7 call eraserect
;

: blackBar { rect pixels | locBR locTL }
 rect ^ locTL 8 cmove
 ^ locBR w@ ( bottom ) pixels -
 ^ locTL w!
 ^ locTL call paintrect
;

: #elems { qhdr | elems -- #.of.queue.elements }
 0 -> elems
 2 +> qhdr
 begin
 qhdr @ ?dup while
 -> qhdr
 1 +> elems
 repeat
 elems
;
 
: display.queues {  | -- }
 clr.rects
 draw.rects
 rect1 vblqhdr #elems 4* blackBar
 rect2 vcbqhdr #elems 4* blackBar
 rect3 drvqhdr #elems 4* blackBar
 rect4 evtqhdr #elems 4* blackBar
 rect5  fsqhdr #elems 4* blackBar
 rect6  dtqhdr #elems 4* blackBar
 rect7 timevars @ 8 + #elems 4* blackBar
;

: dsp.vbl { | qelemPtr n -- }
 cls
 qinfo “ Vertical Blanking Tasks” 
 call SetWTitle
 .” ----------------------------------------------------------------” 
cr
 .” task# qtype  ProcPtr Count Phase” cr
 .” ----------------------------------------------------------------” 
cr
 vblqhdr 2+ -> qelemptr
 1 -> n
 begin
 qelemptr @ ?dup while
 -> qelemptr
 n 3 .r 3 spaces 
 hex
 qelemptr 4 + w@ 5 .r space
 qelemptr 6 + @ 8 .r space
 qelemptr 10 + w@ 5 .r space
 qelemptr 12 + w@ 5 .r cr
 decimal
 1 +> n 
 repeat
;

: dsp.vcb { | qelemPtr n -- }
 cls
 qinfo “ Volume Control Blocks” 
 call SetWTitle
 .” --------------------------------------------------------------------------------------------------------------------------------------------------” 
cr
 .”  vcb# qtype Volume name Drive dRef# vRef# #blks blksz free” cr
 .” --------------------------------------------------------------------------------------------------------------------------------------------------” 
cr
 vcbqhdr 2+ -> qelemptr
 1 -> n
 begin
 qelemptr @ ?dup while
 -> qelemptr
 n 3 .r 3 spaces 
 hex
 qelemptr 4 + w@ 5 .r space
 qelemptr 44 + count dup rot swap type
 27 swap - spaces
 qelemptr 72 + w@ 5 .r space
 qelemptr 74 + w@ 5 .r space
 qelemptr 78 + w@ 5 .r space
 qelemptr 26 + w@ 5 .r space
 qelemptr 28 +  @ 5 .r space 
 qelemptr 42 + w@ 4 .r cr
 decimal
 1 +> n 
 repeat
;

: dsp.drv { | qelemPtr n -- }
 cls
 qinfo “ Drives” 
 call SetWTitle
 .” ------------------------------------------------------------------------------------------” 
cr
 .”  drv# qtype Drive dRef# FSID    #blks l dd ss” cr
 .” ------------------------------------------------------------------------------------------” 
cr
 drvqhdr 2+ -> qelemptr
 1 -> n
 begin
 qelemptr @ ?dup while
 -> qelemptr
 n 3 .r 3 spaces 
 hex
 qelemptr 4 + w@ 5 .r space
 qelemptr 6 + w@ 5 .r space
 qelemptr 8 + w@ 5 .r space
 qelemptr 10 + w@ 4 .r space
 qelemptr 12 + w@
 qelemptr 4 + w@ 1 = IF 
 qelemptr 14 + w@ 65536 * + 
 THEN
 8 .r space
 qelemptr 4- c@ $80 AND 
 IF ascii y emit ELSE ascii n emit THEN space
 qelemptr 3- c@ 2 .r 2 spaces 
 qelemptr 1- c@ $80 AND 
 IF ascii n emit ELSE ascii y emit THEN cr
 decimal
 1 +> n 
 repeat
;

: dsp.evt { | qelemPtr n -- }
 cls
 qinfo “ Queued Events” 
 call SetWTitle
 .” ------------------------------------------------------------------------------------------------” 
cr
 .”  drv# qtype What  Message   When     Where  Mods” cr
 .” ------------------------------------------------------------------------------------------------” 
cr
 evtqhdr 2+ -> qelemptr
 1 -> n
 begin
 qelemptr @ ?dup while
 -> qelemptr
 n 3 .r 3 spaces 
 hex
 qelemptr 4 + w@ 5 .r space
 qelemptr 6 + w@ 5 .r space
 qelemptr 8 +  @ 8 .r space
 qelemptr 12 + @ 8 .r space
 qelemptr 16 + @ 8 .r space
 qelemptr 20 + w@ 4 .r cr
 decimal
 1 +> n 
 repeat
;

: dsp.fs 
 cls
 qinfo “ File System Requests” 
 call SetWTitle
;

: dsp.dt
 cls
 qinfo “ Deferred Tasks”
 call SetWTitle
;
 
: dsp.tm { | qelemPtr n -- }
 cls
 qinfo “ Time manager”
 call SetWTitle
 .” ----------------------------------------------------” cr
 .” task# qtype  ProcPtr Count” cr
 .” ----------------------------------------------------” cr
 timeVars @ 10 + -> qelemptr
 1 -> n
 begin
 qelemptr @ ?dup while
 -> qelemptr
 n 3 .r 3 spaces 
 hex
 qelemptr 4 + w@ 5 .r space
 qelemptr 6 +  @ 8 .r space
 qelemptr 10 + w@ 5 .r cr
 decimal
 1 +> n 
 repeat
;

: do.user
 qInfo dup call showwindow call selectwindow
 qInfo taskwindowpointer !
 ( menuID ) CASE
 150 OF dsp.vbl ENDOF
 151 OF  dsp.vcb ENDOF
 152 OF dsp.drv ENDOF
 153 OF  dsp.evt ENDOF
 154 OF dsp.fs  ENDOF
 155 OF  dsp.dt  ENDOF
 156 OF  dsp.tm  ENDOF
 ENDCASE
 SysQueue taskwindowpointer !
;

: do.update  {  | pt  --  }
 sysQueue call setport
 draw.rects
 run-update
;

: do.activate
 event-record modifiers + w@ 
 1 AND  \ Activate event?
 IF   
 call DrawMenuBar
 ELSE
 THEN 
;

: do.close
 bye
;

: INIT-MBAR
 queueBar ADD
 queueBar APPLEMENU ADD   
 APPLEMENU @ ascii DRVR  CALL ADDRESMENU 
 queueBar FileMenu  ADD
 queueBar EditMenu  ADD 
 queueBar vblmenu add
 queueBar vcbmenu add
 queueBar drvmenu add
 queueBar evtmenu add
 queueBar fsmenu add
 queueBar dtmenu add
 queueBar tmmenu add
;

: DO-APPLE   { item# | [ 32 lallot ] daName -- }
 item# 1 =  
 IF3 beep

 ELSE AppleMenu @
 item# ^ DAName CALL GetItem
 ^ DAName CALL OpenDeskAcc DROP
 THEN 
;

: do-file
 drop bye
;

: MBAR-HANDLER  ( item# menuID -  )
 CASE
 APPLEID OF DO-APPLE    ENDOF
 FILEID OF DO-FILE   ENDOF
 drop
 ENDCASE  
 0 CALL HILITEMENU  
;

: go.queue { | mb -- }
 activate

 [‘] do.content content-hook !
 [‘] do.update update-hook ! 
 [‘] mbar-handler menu-vector !
 [‘] do.activate activate-hook !
 [‘] do.close goaway-hook !
 [‘] do.user uservector !

 begin
 pause
 sysQueue call setport
 display.queues
 60 wait
 again
;

: start
 SysQueue add
 QInfo add
 SysQueue queues build
 SysQueue WRefCon + @
 QInfo WRefCon + !
 SysQueue dup call selectwindow call setport
 init-mbar
 queueBar queues mbar>task
 queues go.queue
;

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

BusyCal 3.7.2 - Powerful calendar app wi...
BusyCal is the powerful, flexible, reliable calendar app for macOS. It's packed with time-saving features and compatible with all leading cloud services including iCloud, Google, Exchange and more.... Read more
BusyContacts 1.4.2 - Fast, efficient con...
BusyContacts is a contact manager for OS X that makes creating, finding, and managing contacts faster and more efficient. It brings to contact management the same power, flexibility, and sharing... Read more
iShowU Instant 1.3.0 - Full-featured scr...
iShowU Instant gives you real-time screen recording like you've never seen before! It is the fastest, most feature-filled real-time screen capture tool from shinywhitebox yet. All of the features you... Read more
Capo 3.8 - Slow down and learn to play y...
Capo lets you slow down your favorite songs so you can hear the notes and learn how they are played. With Capo, you can quickly tab out your songs atop a highly-detailed OpenCL-powered spectrogram... Read more
Viber 11.7.0 - Send messages and make fr...
Viber lets you send free messages and make free calls to other Viber users, on any device and network, in any country! Viber syncs your contacts, messages and call history with your mobile device, so... Read more
Drive Genius 5.3.1 - $79.00
Drive Genius features a comprehensive Malware Scan. Automate your malware protection. Protect your investment from any threat. The Malware Scan is part of the automated DrivePulse utility. DrivePulse... Read more
CorelDRAW 21.2.0.708 - Graphic design so...
CorelDRAW - professional graphic design software for vector illustration, layout, and so much more. Get started quickly and easily with a wealth of intuitive tools, built-in learning materials,... Read more
Navicat Premium Essentials 12.1.27 - Pro...
Navicat Premium Essentials is a compact version of Navicat which provides basic and necessary features you will need to perform simple administration on a database. It supports the latest features... Read more
OmniFocus 3.4.3 - GTD task manager with...
OmniFocus is an organizer app. It uses projects to organize tasks naturally, and then add tags to organize across projects. Easily enter tasks when you’re on the go, and process them when you have... Read more
Microsoft OneNote 16.30 - Free digital n...
OneNote is your very own digital notebook. With OneNote, you can capture that flash of genius, that moment of inspiration, or that list of errands that's too important to forget. Whether you're at... Read more

Latest Forum Discussions

See All

Upcoming mobile MMO TeeTINY Online’s sec...
TeeTINY Online is an upcoming anime-themed MMO which boasts striking visuals and an ambitious open world to explore. Following a successful CBT (closed beta test) on Android, developer TEENY.studio has now released a follow-up test which adds an... | Read more »
Breakout: Dark Prison is a fast-paced ac...
Breakout: Dark Prison is an action RPG from LaterSoft. Set in the aftermath of a deadly virus outbreak your daughter has been taken from you because she has an immunity to the illness in her DNA. Not being a fan of experimentation on children –... | Read more »
Apple Arcade in review
This weekend, Apple Arcade will officially be one month old. That means anyone who signed up for the free trial on day one has a decision to make: Stick with the service and shell out $5 a month, or cancel and go about your merry way. | Read more »
Alluris is a choose-your-own adventure g...
Alluris is an RPG that the developer's are calling a swipe-your-own adventure game. This is because the game incorporates a Reigns-style - swiping left or right - selection mechanic to make all the decisions you'd usually expect to make across... | Read more »
Hello Hero All Stars receives update wit...
The first Hello Hero game hit global platforms in 2013 and proved a huge success, with developer Fincon adding two more entries to this popular series of casual RPG games since. Released in June this year, Hello Hero All Stars brings many of the... | Read more »
Zombieland: Double Tapper, a cartoon idl...
Zombieland: Double Tapper is the idle RPG tie-in to the upcoming Zombieland: Double Tap. Oddly, it's one of two different Zombieland games launching today, with the other being the Switch title Zombieland: Double Tap - Road Trip. [Read more] | Read more »
Rusty Lake's The White Door launche...
Rusty Lake and Second Maze's intriguing point-and-click adventure game, The White Door, is now up for pre-order on the App Store. This one sees you playing as Robert Hill, a mental health patient who is suffering from severe memory loss. The game... | Read more »
Hellrule is an auto-runner inspired by G...
Hellrule is an upcoming auto-runner game from independent developer Pedrocorp where players will take control of a dapperly dressed gentlemen who comes equipped with a razor-sharp umbrella for slicing up his foes. The game will be available for... | Read more »
Grobo is a gravity bending puzzle platfo...
Grobo is a 2D puzzle platformer that marks the first release from developers Hot Chocolate Games. You'll find yourself manipulating gravity as you make your through this title that's available now for iOS and Android. [Read more] | Read more »
Adrenaline, Compulsive Entertainment’s h...
Compulsive Entertainment’s high-octane arcade racer, Adrenaline, has now made its way to the App Store following a successful launch on Google Play. It’s a ton of challenging, fast-paced fun, boasting easy-to-learn controls and a varied selection... | Read more »

Price Scanner via MacPrices.net

11″ WiFi iPad Pros on sale today for up to $2...
Amazon has new 2018 Apple 11″ WiFi iPad Pros in stock today and on sale for up to $250 off Apple’s MSRP. These are the same iPad Pros sold by Apple in its retail and online stores. Be sure to select... Read more
Apple offers clearance 2018 15″ 6-Core MacBoo...
Apple has clearance 2018 15″ 6-Core Touch Bar MacBook Pros, Certified Refurbished, available starting at only $1999. Each model features a new outer case, shipping is free, and an Apple 1-year... Read more
Apple continues to offer refurbished 2019 21″...
Apple has Certified Refurbished 2019 21″ & 27″ iMacs available starting at $929 and up to $350 off the cost of new models. Apple’s one-year warranty is standard, shipping is free, and each iMac... Read more
Verizon offers free iPhone 7 for customers wh...
Verizon is offering a free 32GB iPhone 7 for new or existing customers who open a new line of service, no trade-in required. Cost of the phone is credited to your account monthly for 24 months. The... Read more
13″ 2.4GHz 4-Core MacBook Pros remain availab...
Apple has a full line of Certified Refurbished 2019 13″ 2.4GHz 4-Core Touch Bar MacBook Pros available starting at $1529 and up to $300 off MSRP. Apple’s one-year warranty is included, shipping is... Read more
Lease one iPhone Xs, Xr, or X at Sprint and g...
Purchase an Apple iPhone X, Xr, Xs, or Xs Max at Sprint, and get a 64GB iPhone Xr for free. Requires 2 new lines or 1 upgrade-eligible line and 1 new line. The fine print: “iPhone Xs (64 GB) $37.50/... Read more
How to use your Apple Education discount to s...
Purchase a new MacBook Pro or MacBook Air using Apple’s Education discount, and take up to $200 off MSRP. All teachers, students, and staff of any educational institution with a .edu email address... Read more
Base 2019 13″ 1.4GHz 4-Core MacBook Pro on sa...
Amazon has the new 2019 13″ 1.4GHz/128GB 4-Core Space Gray Touch Bar MacBook Pro on sale for $100 off Apple’s MSRP. This is the same MacBook Pro sold by Apple in its retail and online stores: – 2019... Read more
Save up to $30 on Apple’s AirPods at these re...
Amazon is offering discounts on new 2019 Apple AirPods ranging up to $30 off MSRP. Shipping is free: – AirPods with Charging Case: $144 $15 off MSRP – AirPods with Wireless Charging Case: $169 $30... Read more
Save $15 on Apple Watch Series 5 models on Wa...
Walmart has new Apple Watch Series 5 models on sale for $15 off Apple’s MSRP on their online store. Choose free shipping or free local store pickup (if available). Sale prices for online orders only... Read more

Jobs Board

Best Buy *Apple* Computing Master - Best Bu...
**734688BR** **Job Title:** Best Buy Apple Computing Master **Job Category:** Store Associates **Location Number:** 000297-Reston-Store **Job Description:** The Core Read more
Best Buy *Apple* Computing Master - Best Bu...
**738529BR** **Job Title:** Best Buy Apple Computing Master **Job Category:** Sales **Location Number:** 000258-Lewisville-Store **Job Description:** **What does a Read more
*Apple* Mobility Pro - Best Buy (United Stat...
**741888BR** **Job Title:** Apple Mobility Pro **Job Category:** Store Associates **Location Number:** 000870-N Scottsdale-Store **Job Description:** At Best Buy, Read more
*Apple* Mobile App Developer - eiWorkflow So...
…eiWorkflow Solutions, LLC is currently looking for a consultant for the following role. Apple Mobile App Developer Tasks the role will be performing: ? Mobile App Read more
Essbase Developer - *Apple* - Theorem, LLC...
Job Summary Apple is seeking an experienced, detail-minded Essbase developer to join our worldwide business development and strategy team. If you are someone who Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.