TweetFollow Us on Twitter

Segments
Volume Number:4
Issue Number:11
Column Tag:Forth Forum

Code Segments & Linker

By Jörg Langowski, MacTutor Editorial Board

Code segments and a Mach 2 linker

This month I’d like to report on some recent Mach2 improvements: the new 2.14 version and a linker for kernel-independent applications that has recently appeared on the GEnie Mach2 roundtable. Since many of you don’t have access to that BBS, I’ll document the linker here, with some review of code segment structure, and put the code on the source code disk.

Single-segment linker

We have seen several examples - DAs, XCMDs, MDEFs - of Mach2 code that runs independent of the Forth multitasking kernel. Writing such code requires that the programmer write the setup code that is usually provided by the Mach2 system. For the examples that I gave in my column, the standard glue code for making a routine callable from outside Mach2 looked similar to:

CODE prelude
 LINK A6,#-Nstack  
 \ Nstack bytes of local Forth stack
 MOVEM.L A0-A5/D0-D7,-(A7)\ save registers 
 MOVE.L A6,A3  \ setup local loop return stack
 SUBA.L #Nlocal,A3 \ in the low Nlocal stack bytes
 MOVE.L 8(A6),D0 \ pointer to parameter block 
 MOVE.L D0,-(A6)
 RTS  \ just to indicate the MACHro stops here 
END-CODE MACH

CODE epilogue
 MOVEM.L (A7)+,A0-A5/D0-D7\ restore registers 
 UNLK A6
 MOVE.L (A7)+,A0 \ return address
 ADD.W  #4,A7  \ pop off 4 bytes of parameters
 JMP    (A0)
 RTS
END-CODE MACH

: my-forth-code
 ( code to be called externally )
;

: ext.routine
 prelude my-forth-code epilogue
;

After these definitions, the routine ext.routine may be called from the outside as if defined in Pascal as:

procedure ext.routine (parameter:longint);
begin
 ( code to be called externally )
end;

All we need in this case before calling our Forth code is to set up a local Forth stack maintained by the A6 register, save all the registers for safety, and create a loop return stack maintained by A3.

In principle, a complete application can be created this way; however, some more setup is required. A simple one-segment application consists of two CODE resources: the jump table in CODE 0 and the actual code in CODE 1. The structure of the jump table (JT) as given in IM II-60 looks like the following (in the case that the first entry in the JT corresponds to a routine in segment 1):

0: longintAbove A5 size ( 32 + length of JT )
4: longintBelow A5 size (appl. and QD globals)
8: longintLength of jump table in bytes
12:longint  Offset from A5 to jump table (32 )
16:Jump table:
 ------ Jump table entry #1 ------
 word   offset of routine #1 from beginning of
 segment
 longintMOVE.W #1,-(A7)
 ( push segment # of routine on stack)
 word   _LoadSeg
 ------ following jump table entries ----
 ------ for routine #2...n, if necessary ------

When an application is launched, the CODE 0 resource will be loaded and the first JT entry executed. This will load the appropriate segment into memory and jump to the routine to which the first entry is pointing. Thus, a simple one-segment application would consist of a CODE 0 resource like above, with one single JT entry:

 $nnnn  ( entry address in CODE 1 segment )
 ( attention: segment starts at )
 ( beginning of resource + 4)
 $3F3C0001( MOVE.W #1,-(A7) )
 $A9F0  ( _LoadSeg )

CODE 1 would contain the actual code, written in Mach2.

What are the advantages of creating single-segment Mach2 programs? First of all, we can create very small applications. The smallest conceivable application, which does absolutely nothing but return, would comprise only 30 bytes:

CODE 0:
 $00000028( always $20 + length(JT) )
 $00000200( arbitrary )
 $00000008( length of JT; one entry )
 $00000020( always )
 $0000  ( entry address in CODE 1 segment )
 $3F3C0001( MOVE.W #1,-(A7) )
 $A9F0  ( _LoadSeg )
CODE 1:
 $0000  ( first routine is at beginning of JT )
 $0001  ( one entry in this segment )
 $4E75  ( RTS )

This program is enclosed on the source code disk as a curiosity. The file actually is 364 bytes long (Resource map etc.), which is still pretty small.

A second advantage is that we have complete control over the way the application sets itself up. In particular, we could pass a routine pointer to _InitDialogs to activate the Resume button of the system bomb box, or we might want to control the amount of calls to _MoreMasters.

The disadvantage of compiling applications under Mach2: Obviously we have to care about all the things that the kernel normally does for us, like basic event handling, menu and menu bar setup, screen input/output, etc. Particularly, there are quite a few Forth words that may not be used anymore; regular readers of this column should be familiar with the rules for creating ‘kernel-independent code’ that I’ve laid out a few times already.

The Forth words that can be used include:

!  “  +  +!  ^  +>  -  ->  0<  0=  0>  1+  1-  2*  2+  2-  2/  2DROP 
 2DUP  2OVER  <  <>  =  >  >BODY  >R  ?DUP  @  ABS  AND  ASCII  C!  C@ 
 DROP  DUP  EXIT  I  I’  J  LEAVE  L_EXT  NEGATE  NOT  OR   OVER  PAD 
 PICK  R>  R@  SWAP U<  W!  W@  XOR  {   (it’s OK to use local variables)

The following control and branching structures may also be used:

IF  ELSE  THEN  BEGIN  WHILE  REPEAT  UNTIL  AGAIN CASE  ENDCASE  OF 
 ENDOF  DO  LOOP  +LOOP

Assembler, of course, may be used freely.

Waymen Askey, of Palo Alto Shipping, has created a ‘linker’ utility that compiles single-segment application using the strategy given above. We reprint his program in listing 1 with his permission. This linker operates on a program which has the following structure:

PROGRAM  programname;
( definitions not to be included in the final application
such as constants, compiling words, etc. )

VAR
( global variable declarations which will be offset from A5 )

PROCEDURES
( Forth words called by the top level word )

MAIN
( top level word which is called on startup. )
( This word should call the setup procedures )
( MachSetUp and MacintoshSetUp )
( which are provided with the Linker utility. )
END 

The linker computes the ‘below A5’ size from the variables defined after the VAR statement, adding space for the Forth stacks, Quickdraw globals and various other things. The offset of the MAIN entry point into the code segment is calculated and the jump table set up. MakeJumpTable and MakeMain are the words that create the jump table and code segment 1.

MachSetUp initializes the registers for Mach2 usage. Floating point (D7), parameter (A6) and return (A3) stacks are created above the current stack base in the application globals area. The A7 stack, starting at CurStackBase, remains unaffected. The application globals area is then cleared.

MacintoshSetUp does the standard initialization calls to _MoreMasters, _InitGraf, _InitFonts, _InitWindows, _InitMenus, _TEInit, _InitDialogs, _FlushEvents and _InitCursor.

After these initialization calls, the main program may be entered. An example of a short program which creates a window and beeps is given in the listing. This program, too, is only 858 bytes long (!!!).

Mach 2.14 upgrade

For those of you who haven’t yet upgraded to Mach2.14, I’ll briefly review the latest changes.

1. CASE optimization: redundant instruction sequences of the type

 MOVE.L  D0,-(A6)
 MOVE.L (A6)+,D0

are no longer generated.

2. Local variable handling: the new release offers access to the local variable compiler with the words LALLOT and LP@. For example, a word might define a local 16-byte buffer in the following way:

 : EXAMPLE  {  |  [ 12 LALLOT ] myBuffer --  }
 CR  .” Please enter your name “
 ^ myBuffer  16 EXPECT
 CR .” Hello “  ^ myBuffer  SPAN @  TYPE ;

The local variable compiler can be further enhanced through ‘local variable compiling words’; examples on how to do this are given on the 2.14 release disk.

3. Disassembler: References to USER and global variables are now given with their Forth names. Disassembly speed has been greatly improved, which is particularly evident when executing IL on a Mac Plus or SE. 68881 opcodes are now supported, however, 68020-specific instructions not yet.

4. New words: ASCII now takes up to four characters, for easy definition of resource types. 4+, 4-, 4*, 4/ have been added. a n SHIFT will shift a 32-bit word a by n bits.

5. The trap list has been updated.

Feedback dept.

“Dear Jörg,

I saw a discussion of accented character problems in the July MacTutor and thought I would throw in a few digressions on that matter.

First, you and your readers might be interested to know that Apple has removed the scaron and zcaron characters from the new NTX PROMs against the recommendation of Adobe. These characters were not accessible from the keyboard, because they are uncoded, meaning that no ASCII value is assigned. The only way to access them is via Postscript character names. The good news is that several new characters were added making the NTX almost compliant with the ISO 8859 character set that Adobe routinely supplies with all new fonts. (Apple removed the ´y and ´Y, too).

For those of you who want to see the unencoded characters, you can get at them with the following Postscript code and a download utility, if you have one of the new unprotected Adobe fonts or a late model Laserwriter Plus with v.3 PROMs:

/Garamond-Light findfont dup length dict
 /newdict exch def
{1 index /FID 
 ne{ newdict 3 1 roll put }{ pop pop }ifelse
 } forall
/Encoding 256 array def
Encoding 0 /Garamond-Light findfont
/Encoding get 0 256 getinterval putinterval
Encoding 127 /DEL put
Encoding 129 /lslash put
Encoding 130 /Lslash put
Encoding 131 /eth put
Encoding 132 /Eth put
Encoding 133 /thorn put
Encoding 134 /Thorn put
Encoding 135 /onehalf put
Encoding 136 /onequarter put
Encoding 137 /threequarters put
Encoding 138 /brokenbar put
Encoding 139 /onesuperior put
Encoding 140 /twosuperior put
Encoding 141 /threesuperior put
Encoding 142 /scaron put
Encoding 143 /Scaron put
Encoding 144 /zcaron put
Encoding 145 /Zcaron put
Encoding 146 /yacute put
Encoding 147 /Yacute put
newdict /Encoding Encoding put
/IsoGaramond newdict definefont pop
/IsoGaramond findfont 18 scalefont setfont
75 250 moveto 
(ÄÅÇÉÑÖÜáàâäãåçéèêëíì Garamond) show
showpage

Unfortunately there is no way, at present, to get at these with templates in Fontographer, so you have to make your own composites, if you want to add these characters to PostScript fonts.

Best regards, Tim Ryan

SourceNet

P.O.Box 6767

Santa Barbara, CA 93160

PS: The standalone caron () is frequently found as ASCII character 255, one of the last four untypeable characters. It can be accessed using QUED, ... and MS Word if you enter the character using its ASCII value.

By the way, I did get a Greek + Hebrew System from Apple-France via persistent phone calls.

I’ve enclosed the first draft of an article that will appear in my forthcoming book “The Macintosh Book of Fonts”. If you’re interested in reprinting the final draft when it’s available, let me know.

Tim “

Thanks, Tim, for that interesting letter (I’ve enclosed your Postscript code on the source code disk). Now if all these characters were defined somewhere in the standard fonts, wouldn’t that be nice? I always wondered why there were so many empty places in the font definition tables, seems like a waste of space to me

In the next issue we’ll introduce - with other contributions from this side of the Atlantic - a very nice and powerful utility for changing keyboard definitions, so at least that problem can be overcome. Till then.

Listing 1: Mach 2.14 single-segment linker
\ © Waymen Askey c/o Palo Alto Shipping
\ Reprinted with permission. -- JL

\ Guidelines for use of the single-segment “linker.”
\ This utility is NOT meant to replace the
\ standard Mach TURNKEY process.  Its use (at present)
\ is limited to creating small (one-segment, less than
\ 32K) programs which do NOT require the multi-tasking,
\ I/O, and  auto event-handling support which the normal
\ turnkey process supplies.  
\ Also, since this utility is being supplied free to
\ Mach users, Palo Alto Shipping will NOT assume
\ responsibility for support of the utility, nor
\ will we be held responsible for any errors (bugs)
\ which it may produce.
\ It should, however, point the way for other
\ compiler enhancements by users.  The “bottom line” is
\ that Mach can be used to create any type (and size) of 
\ Macintosh application, DA, driver, INIT, etc.  
\ Waymen @ PASC

(
\ The following words MAY be used freely within the 
\ stand-alone, “linked” application.
\

!  “  +  +!  ^  +>  -  ->  0<  0=  0>  1+  1-  2*  2+  2-  
2/  2DROP  2DUP  2OVER  <  <>  =  >  >BODY  >R  ?DUP  @  
ABS  AND  ASCII  C!  C@  DROP  DUP  EXIT  I  I’  J  LEAVE  
L_EXT  NEGATE  NOT  OR   OVER  PAD  PICK  R>  R@  SWAP
U<  W!  W@  XOR  {   (it’s OK to use local variables)
    
\ The following control and branching structures MAY
\ also be used.
\
IF  ELSE  THEN  BEGIN  WHILE  REPEAT  UNTIL  AGAIN  
CASE  ENDCASE  OF  ENDOF  DO  LOOP  +LOOP

\ All assembler words may be used.

\  The following compilation words MAY be used to
\ create your application  (but don’t attempt to
\ compile them, they can’t be executed during the 
\ run-time of your finished application).
\ 
:  ;  VARIABLE  CONSTANT  USER  CREATE  DOES>  
;CODE  CODE  END-CODE  ALLOT  VALLOT  ,  W,  C,  
HERE  COMPILE  [COMPILE]  IMMEDIATE  SMUDGE  LITERAL
LAST  MACH  RECURSIVE  [  ]  
\ Note, global variables may ONLY be used if you
\ declare a VAR block.

\ [‘] should be used with caution.
\ Don’t use it on words defined outside of your
\ program block.
\ If you wish to use EXECUTE, it may be redefined as
\
CODE EXECUTE  ( a -- )
  MOVE.L (A6)+,A0
  JSR (A0)
  RTS
END-CODE MACH

\ ONLY the following MAC vocabulary words MAY be used.
\ Remember to use  (CALL)  instead of  CALL.
\
(CALL)  All CONSTANTS used for the creation of user
interface structures (CLOSEBOX, VISIBLE, etc.)
If you define a VAR block, EVENT-RECORD (and all
other system global variables) may be
used as a storage area only -- events (and other 
information) will NOT automatically be posted
there).
\ These utilities may also be used.
TRAP#  TRAPLIST  TRAPNAME


\ ====================================
\ ========== Can’t Use These ============
\ Words which may NOT be used!!!  This is NOT a
\ complete list, just some of the more common words.
\ You must NOT compile any word which is referenced
\ through Mach’s own jump table (words which compile
\ a JSR d(A5) instruction.
\ 
CALL  GLOBAL  TERMINAL  TURNKEY  NEW.WINDOW  ADD (etc.)
BUILD  TASK  TASK->  BYE  EVENT-TABLE  PAUSE
All I/O such as  KEY  EXPECT  EMIT  .”  TYPE  (etc.)
<#  #  #S  #>  DEPTH  2SWAP  CMOVE  *  /  /MOD  */MOD  */
(if you are using a Mac II exclusively, you may substitute the new 32-bit 
math routines which came with the last Mach upgrades.)  NO SANE words, 
 NO TALKing words,
NO I/O words.  None of the “high-level” FILE words in
the MAC vocabulary.  NO words which reference the 
multi-tasking kernel, NO I/O task words (i.e. events
MUST be handled explicitly, you must create your own
event-loop).
A space for USER variables is reserved for your
program, but all of them (except for the TIB value,
S0, and RETURN_STK) are initialized to zero.
Consider USER variables as just another global storage
area.  Words like BASE and (ABORT) may be used; however, they will have 
NO effect on your program unless you specifically design the words to 
use them. 
)

\ ----------------------------------------------------------------------
\ A simple, one-segment linker which may
\ be used (with restrictions) to create
\ small applications in high-level Forth.
\ Also allows you to create very small assembly
\ language programs (mininum size about 40 bytes)
\ With slight modifications to the “linker” and the
\ proper SetUp word, could also be used 
\ to create DA’s, FKEY’s, XCMD’s, and INIT’s.
\ -- Waymen 
\ @ Palo Alto Shipping Company

ONLY MAC ALSO FORTH DEFINITIONS
DECIMAL

$908    CONSTANT CurStackBase
$434F4445 CONSTANT ‘CODE’
$4150504C CONSTANT ‘APPL’
$3F3F3F3F CONSTANT ‘????’
%1 CONSTANT MainErr
%10CONSTANT EndErr
%100    CONSTANT ProcErr
$12344320 CONSTANT GoodStart
$1234432F CONSTANT StartFlag
$12344328 CONSTANT GoodEnd

\ The default stack and USER variable sizes
\ to be used in building the jump table.
\ I’ve made the USER size larger to allow
\ for a 256 byte PAD
572CONSTANT USERSize ( USER variables)
74 CONSTANT TIBSize( plus STATUS)
600CONSTANT ParameterSize ( A6 & A3 stacks)
200CONSTANT FPSize ( FP stack)
206CONSTANT GrafSize ( QD globals)

$20CONSTANT BL
-1 CONSTANT TRUE
0CONSTANT FALSE

VARIABLE VarEntry
VARIABLE SegmentEntry
VARIABLE MainEntry
VARIABLE SegmentEnd
VARIABLE ProgramFlag
VARIABLE ProgramName 28 VALLOT
VARIABLE JumpTable 20 VALLOT


: -Leading  {  addr cnt | whiteSpace -- addr’ cnt’  }
\ Adjusts addr and cnt to “strip” leading spaces from a string.
\ Addr is the starting character address,
\ cnt is the original length.
 0  -> whiteSpace
 BEGIN
 addr whiteSpace +  C@  BL =
 whiteSpace cnt <  AND
 WHILE
 1  +> whiteSpace
 REPEAT
 addr whiteSpace +
 cnt whiteSpace - ;

: RemoveSpaces  {  addr | cnt  --  }
\ Given counted string at addr, remove trailing and leading 
\ spaces and repack string.
 addr COUNT  -TRAILING  addr C!  DROP
 addr COUNT  -Leading  -> cnt  
 ( addr’) addr 1+  cnt  CMOVE  cnt addr C! ;

: Scan  {  addr num delimiter | cnt char -- flag  }
\ Scans input stream, placing characters into string at addr until 
\ num characters are received or delimiter is found.
\ If delimiter is NOT found prior to num, return FALSE
\ else return TRUE.
 num 0>
 IF
 0  -> cnt
 BEGIN
 0 WORD  1+  C@  -> char
 char  delimiter = NOT
 num cnt  >  AND
 WHILE
 1  +> cnt  char  addr cnt +  C!
 REPEAT
 cnt addr C!  char delimiter =
 ELSE
 0 addr !  FALSE
 THEN ;

: PROGRAM  {  | cnt scanFlag --  }
\ Gets program name and init’s linker variables.
 ProgramName  31  ASCII ;   Scan  -> ScanFlag
 ProgramName RemoveSpaces

 ProgramName C@ 0=  scanFlag 0=  OR  
 ABORT” Must use  ; to delimit program name!”

 0 MainEntry !  0 SegmentEnd !  0 VarEntry !  
 StartFlag ProgramFlag ! ;

: ClearErr  ( errNum -- )
 ProgramFlag @  XOR  ProgramFlag  ! ;

: VAR  ( -- )
\ Ensure that current VP offset from A5 is
\ even, then save it.
 VP @   1 AND 
 IF
 1 VALLOT
 THEN  VP @  ABS VarEntry ! ;

: Globals?  ( -- )
\ Checks to see if a VAR statement was made.
 VarEntry @  0=
 IF
 10 CALL SysBeep
 CR .” WARNING: No global variables were declared!”
 THEN ;

: ?HERE  ( -- a )
\ Ensures that HERE pointer is even, then
\ returns HERE.
 HERE  1 AND 
 IF
 1 ALLOT
 THEN  HERE ;

: PROCEDURES  ( -- )
 ProcErr  ClearErr
 ?HERE SegmentEntry !  4 ALLOT ; 

: MAIN  ( -- )
 MainErr ClearErr
 ?HERE  MainEntry ! ;

: END  ( -- )
 EndErr  ClearErr
 ?HERE  SegmentEnd ! ;

: ZeroFlags  ( -- )
 0 ProgramFlag !  0 VarEntry !  
 0 MainEntry !  0 SegmentEnd ! ;

: BelowA5  ( -- n )
\ Calculates the Below A5 space for
\ the jump table.
 VarEntry @  DUP  0=
 IF
 DROP  GrafSize
 THEN
 USERSize +  TIBSize +
 ParameterSize +  FPSize + ;   

: MakeJumpTable  ( -- handle f )
\  handle is to a generic, one-entry jump table.
 $00000028JumpTable! \ Above A5 size
 BelowA5JumpTable 4 +!  
 \ Global variable space
 $00000008JumpTable 8 + !
 \ Jump table length
 $00000020JumpTable 12 +  ! 
 \ Jump table A5 offset 

 \ Calculate segment entry point
 MainEntry @  SegmentEntry @  4 +  -
 ( entry) JumpTable 16 +  W! 
 $3F3C0001JumpTable 18 +  ! 
 \ MOVE.W #1,-(A7)
 $0001A9F0JumpTable 22 +  W!
 \ _LoadSeg
 JumpTable  24  CALL PtrToHand ;

: MakeMain  ( -- handle f )
 \ Offset to first jump-table entry
 0  SegmentEntry @  W!
 \ Only one jump-table entry
 1  SegmentEntry @  2+  W!
 SegmentEntry @  ( start of segment )
 SegmentEnd @  SegmentEntry @  -   ( length of segment )
 CALL PtrToHand ;
 
: Link  {  refNum |  JumpHandle  MainHandle --  }
\ Creates, then adds CODE segments 0 and 1 
\ to file refNum
 refNum
 IF
 MakeJumpTable  
 IF
 ZeroFlags
 refNum  CALL CloseResFile
 CR .” MakeJumpTable error!”  ABORT
 THEN 
 -> JumpHandle
 JumpHandle  ‘CODE’  0  “ Jump Table”  
 CALL AddResource
 CALL ResError  
 IF
 ZeroFlags
 refNum  CALL CloseResFile
 JumpHandle  CALL DisposHandle  DROP
 CR  .” Link (0): AddResource error!”  ABORT
 THEN

 MakeMain
 IF
 ZeroFlags
 refNum  CALL CloseResFile
 JumpHandle  CALL DisposHandle  DROP
 CR .” MakeMain error!”  ABORT
 THEN
 -> MainHandle
 MainHandle  ‘CODE’  1  “ Main”  
 CALL AddResource
 CALL ResError
 IF
 ZeroFlags
 refNum  CALL CloseResFile
 JumpHandle  CALL DisposHandle  DROP
 MainHandle  CALL DisposHandle  DROP
 CR .” Link (1): AddResource error!” ABORT
 THEN
 THEN ;

: CreateApplFile  {  | refNum --  refNum or zero }
\ Remember to delete previously made files!
 0  -> refNum  
 ‘????’ ‘APPL’ ProgramName  0  CreateFile
 DISK 4 +  W@  0=
 IF
 ProgramName  CALL CreateResFile
 ProgramName  CALL OpenResFile
 \ This logic returns either a valid refNum or zero,
 \ as OpenResFile returns a -1 if it can’t open the file.
 DUP  -1 =  NOT AND  -> refNum  
 THEN  refNum ;

: ?Error  {  errFlag --  }
\ Checks for proper program headings
 errFlag  GoodEnd  XOR
 IF
 CR  .” Missing: “
 errFlag $FFFFFFF0 AND  GoodStart  = 
 IF
 errFlag %111 AND
 CASE
 MainErr  OF.” MAIN “ ENDOF
 EndErr  OF .” END “  ENDOF
 ProcErr  OF.” PROCEDURES “
 ENDOF
 ( else)
 .” MAIN, END and/or PROCEDURES “
 ENDCASE
 ELSE
 .” PROGRAM “
 THEN
 .” Statement(s)!”  ZeroFlags  ABORT
 THEN ;
 
: MakeApplication  {   | refNum --  }
 ProgramFlag @  ?Error
 CreateApplFile  -> refNum
 refNum
 IF
 refNum Link  Globals?
 refNum  CALL CLoseResFile
 ZeroFlags
 ELSE
 CR .” CreateFile error #”  DISK 4 + W@  L_EXT  .
 ZeroFlags  ABORT
 THEN ;

\ ============================================
\ All of the code previous to here will NOT be included
\ in the linked program.  Thus, the above utilities may be
\ workspaced, used and/or enhanced at will.
\ MachSetUp and MacintoshSetUp should appear as the 
\ first statements in your MAIN or LAUNCH word.

CODE MachSetUp  ( -- )
\ Sets up stacks for high-level Forth.
\ Not needed if you work only in assembly language.
 MOVE.L CurStackBase,D0
 MOVE.L D0,D1
 ADD.L #FPSize,D0
 MOVE.L D0,D7  \ FP stack
 MOVEA.L D0,A3 \ “loop” stack
 ADD.L #ParameterSize,D0
 MOVEA.L D0,A6 \ parameter stack
 ADD.L #TIBSize,D0
 MOVEA.L D0,A4 \ USER variables
 MOVEA.L D1,A0
 MOVE.L A5,D0
 SUB.L D1,D0\ below A5 bytes to clear
 DIVU.W #16,D0
 MOVE.W D0,D2  \ “blocks” to clear
 SWAP.W D0\ bytes to clear
 \ Init all globals, USER
 \ vars and stack area to zeros
 BRA.S @20
@10CLR.L (A0)+
 CLR.L (A0)+
 CLR.L (A0)+
 CLR.L (A0)+
@20DBF D2,@10
 BRA.S @40
@30CLR.B (A0)+
@40DBF D0,@30
 \ Although it can’t really be used,
 \ here I set-up the (TIB) USER var
 MOVE.L A6,24(A4)
 MOVE.L A6,4(A4) \ S0 USER var
 MOVE.L A3,12(A4)\ RETURN_STK USER var
 RTS
END-CODE MACH

CODE MacintoshSetUp  ( -- )
 _MoreMasters
 _MoreMasters
 PEA -4(A5)
 _InitGraf
 _InitFonts
 _InitWindows
 _InitMenus
 _TEInit
 CLR.L -(A7)
 _InitDialogs
 MOVE.L #$0000FFFF,D0
 _FlushEvents
 _InitCursor
 RTS
END-CODE MACH
 
\ =============================================
\ ============= An Example =====================

\ From this point on (between the PROCEDURES and END 
\ statement) is where you place your application code.         
PROGRAM My Example;
\ The required and beginning statement in your program.
\ The application will be titled as whatever appears 
\ between the PROGRAM statement and the delimiting 
\ colon (up to 31 characters).
 \ Words defined here 
 \ will NOT be included in your application
 \ The redefintion of CALL is just a reminder.
: CALL  
 CR .” Don’t use CALL here, use (CALL) instead.”  
 ABORT ;  

 0 CONSTANT NIL
 -1 CONSTANT InFront
 10 CONSTANT TenTicks
 30 CONSTANT HalfSecond

VAR
\ All global variables used within the program MUST follow
\ the VAR statement.  If you don’t include the VAR 
\ statement, a warning will be given during program link.  
\ If you don’t use global variables (or Mach system 
\ globals), you may ignore the warning. 
 VARIABLE DelayTicks
 VARIABLE BoundsRect 4 VALLOT
PROCEDURES
\ All subroutines must appear between PROCEDURES and 
\ MAIN. Only that code appearing between the 
\ PROCEDURES and END statements will appear in your 
\ finished application.

 : SetDelay ( n -- ) DelayTicks ! ;
 : Beeper  {  beepTime --  }
 HalfSecond  TenTicks
 DO  
 beepTime  (CALL) SysBeep
 I SetDelay  
 DelayTicks @  (CALL) Delay  DROP  
 TenTicks +LOOP ;
 : MakeWindow  ( -- a | returns a window pointer)
 BoundsRect 20 72 492 322  (CALL) SetRect
 NIL  BoundsRect  “ Beeper Window” VISIBLE
 NOGROW  InFront  NOCLOSEBOX  NIL  
 (CALL) NewWindow ;      
 
 : ProgramLoop  {  | windowPointer --  }
 NIL  -> windowPointer
 MakeWindow  -> windowPointer

 10 Beeper
 
 windowPointer 0= NOT
 IF
 10  (CALL) SysBeep
 windowPointer “ BYE”  (CALL) SetWTitle
 60  (CALL) Delay  DROP
 windowPointer  (CALL) DisposWindow
 THEN ;
MAIN
\ The program’s entry point must appear immediately
\ after  MAIN
 : LAUNCH  ( -- )
 \ Don’t attempt to use local variables in the 
 \ LAUNCH word. The stacks aren’t created until 
 \ after MachSetUp.
 MachSetUp
 MacintoshSetUp
 ProgramLoop ;
END ( of program “My Example”)
\ This statement does error checking 
\ and creates the application.
MakeApplication

CR .( An application called “My Example” has been created.)

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Posterino 4.4 - Create posters, collages...
Posterino offers enhanced customization and flexibility including a variety of new, stylish templates featuring grids of identical or odd-sized image boxes. You can customize the size and shape of... Read more
Chromium 119.0.6044.0 - Fast and stable...
Chromium is an open-source browser project that aims to build a safer, faster, and more stable way for all Internet users to experience the web. List of changes available here. Version for Apple... Read more
Spotify 1.2.21.1104 - Stream music, crea...
Spotify is a streaming music service that gives you on-demand access to millions of songs. Whether you like driving rock, silky R&B, or grandiose classical music, Spotify's massive catalogue puts... Read more
Tor Browser 12.5.5 - Anonymize Web brows...
Using Tor Browser you can protect yourself against tracking, surveillance, and censorship. Tor was originally designed, implemented, and deployed as a third-generation onion-routing project of the U.... Read more
Malwarebytes 4.21.9.5141 - Adware remova...
Malwarebytes (was AdwareMedic) helps you get your Mac experience back. Malwarebytes scans for and removes code that degrades system performance or attacks your system. Making your Mac once again your... Read more
TinkerTool 9.5 - Expanded preference set...
TinkerTool is an application that gives you access to additional preference settings Apple has built into Mac OS X. This allows to activate hidden features in the operating system and in some of the... Read more
Paragon NTFS 15.11.839 - Provides full r...
Paragon NTFS breaks down the barriers between Windows and macOS. Paragon NTFS effectively solves the communication problems between the Mac system and NTFS. Write, edit, copy, move, delete files on... Read more
Apple Safari 17 - Apple's Web brows...
Apple Safari is Apple's web browser that comes bundled with the most recent macOS. Safari is faster and more energy efficient than other browsers, so sites are more responsive and your notebook... Read more
Firefox 118.0 - Fast, safe Web browser.
Firefox offers a fast, safe Web browsing experience. Browse quickly, securely, and effortlessly. With its industry-leading features, Firefox is the choice of Web development professionals and casual... Read more
ClamXAV 3.6.1 - Virus checker based on C...
ClamXAV is a popular virus checker for OS X. Time to take control ClamXAV keeps threats at bay and puts you firmly in charge of your Mac’s security. Scan a specific file or your entire hard drive.... Read more

Latest Forum Discussions

See All

‘Monster Hunter Now’ October Events Incl...
Niantic and Capcom have just announced this month’s plans for the real world hunting action RPG Monster Hunter Now (Free) for iOS and Android. If you’ve not played it yet, read my launch week review of it here. | Read more »
Listener Emails and the iPhone 15! – The...
In this week’s episode of The TouchArcade Show we finally get to a backlog of emails that have been hanging out in our inbox for, oh, about a month or so. We love getting emails as they always lead to interesting discussion about a variety of topics... | Read more »
TouchArcade Game of the Week: ‘Cypher 00...
This doesn’t happen too often, but occasionally there will be an Apple Arcade game that I adore so much I just have to pick it as the Game of the Week. Well, here we are, and Cypher 007 is one of those games. The big key point here is that Cypher... | Read more »
SwitchArcade Round-Up: ‘EA Sports FC 24’...
Hello gentle readers, and welcome to the SwitchArcade Round-Up for September 29th, 2023. In today’s article, we’ve got a ton of news to go over. Just a lot going on today, I suppose. After that, there are quite a few new releases to look at... | Read more »
‘Storyteller’ Mobile Review – Perfect fo...
I first played Daniel Benmergui’s Storyteller (Free) through its Nintendo Switch and Steam releases. Read my original review of it here. Since then, a lot of friends who played the game enjoyed it, but thought it was overpriced given the short... | Read more »
An Interview with the Legendary Yu Suzuk...
One of the cool things about my job is that every once in a while, I get to talk to the people behind the games. It’s always a pleasure. Well, today we have a really special one for you, dear friends. Mr. Yu Suzuki of Ys Net, the force behind such... | Read more »
New ‘Marvel Snap’ Update Has Balance Adj...
As we wait for the information on the new season to drop, we shall have to content ourselves with looking at the latest update to Marvel Snap (Free). It’s just a balance update, but it makes some very big changes that combined with the arrival of... | Read more »
‘Honkai Star Rail’ Version 1.4 Update Re...
At Sony’s recently-aired presentation, HoYoverse announced the Honkai Star Rail (Free) PS5 release date. Most people speculated that the next major update would arrive alongside the PS5 release. | Read more »
‘Omniheroes’ Major Update “Tide’s Cadenc...
What secrets do the depths of the sea hold? Omniheroes is revealing the mysteries of the deep with its latest “Tide’s Cadence" update, where you can look forward to scoring a free Valkyrie and limited skin among other login rewards like the 2nd... | Read more »
Recruit yourself some run-and-gun royalt...
It is always nice to see the return of a series that has lost a bit of its global staying power, and thanks to Lilith Games' latest collaboration, Warpath will be playing host the the run-and-gun legend that is Metal Slug 3. [Read more] | Read more »

Price Scanner via MacPrices.net

Clearance M1 Max Mac Studio available today a...
Apple has clearance M1 Max Mac Studios available in their Certified Refurbished store for $270 off original MSRP. Each Mac Studio comes with Apple’s one-year warranty, and shipping is free: – Mac... Read more
Apple continues to offer 24-inch iMacs for up...
Apple has a full range of 24-inch M1 iMacs available today in their Certified Refurbished store. Models are available starting at only $1099 and range up to $260 off original MSRP. Each iMac is in... Read more
Final weekend for Apple’s 2023 Back to School...
This is the final weekend for Apple’s Back to School Promotion 2023. It remains active until Monday, October 2nd. Education customers receive a free $150 Apple Gift Card with the purchase of a new... Read more
Apple drops prices on refurbished 13-inch M2...
Apple has dropped prices on standard-configuration 13″ M2 MacBook Pros, Certified Refurbished, to as low as $1099 and ranging up to $230 off MSRP. These are the cheapest 13″ M2 MacBook Pros for sale... Read more
14-inch M2 Max MacBook Pro on sale for $300 o...
B&H Photo has the Space Gray 14″ 30-Core GPU M2 Max MacBook Pro in stock and on sale today for $2799 including free 1-2 day shipping. Their price is $300 off Apple’s MSRP, and it’s the lowest... Read more
Apple is now selling Certified Refurbished M2...
Apple has added a full line of standard-configuration M2 Max and M2 Ultra Mac Studios available in their Certified Refurbished section starting at only $1699 and ranging up to $600 off MSRP. Each Mac... Read more
New sale: 13-inch M2 MacBook Airs starting at...
B&H Photo has 13″ MacBook Airs with M2 CPUs in stock today and on sale for $200 off Apple’s MSRP with prices available starting at only $899. Free 1-2 day delivery is available to most US... Read more
Apple has all 15-inch M2 MacBook Airs in stoc...
Apple has Certified Refurbished 15″ M2 MacBook Airs in stock today starting at only $1099 and ranging up to $230 off MSRP. These are the cheapest M2-powered 15″ MacBook Airs for sale today at Apple.... Read more
In stock: Clearance M1 Ultra Mac Studios for...
Apple has clearance M1 Ultra Mac Studios available in their Certified Refurbished store for $540 off original MSRP. Each Mac Studio comes with Apple’s one-year warranty, and shipping is free: – Mac... Read more
Back on sale: Apple’s M2 Mac minis for $100 o...
B&H Photo has Apple’s M2-powered Mac minis back in stock and on sale today for $100 off MSRP. Free 1-2 day shipping is available for most US addresses: – Mac mini M2/256GB SSD: $499, save $100 –... Read more

Jobs Board

Licensed Dental Hygienist - *Apple* River -...
Park Dental Apple River in Somerset, WI is seeking a compassionate, professional Dental Hygienist to join our team-oriented practice. COMPETITIVE PAY AND SIGN-ON Read more
Sublease Associate Optometrist- *Apple* Val...
Sublease Associate Optometrist- Apple Valley, CA- Target Optical Date: Sep 30, 2023 Brand: Target Optical Location: Apple Valley, CA, US, 92307 **Requisition Read more
*Apple* / Mac Administrator - JAMF - Amentum...
Amentum is seeking an ** Apple / Mac Administrator - JAMF** to provide support with the Apple Ecosystem to include hardware and software to join our team and Read more
Child Care Teacher - Glenda Drive/ *Apple* V...
Child Care Teacher - Glenda Drive/ Apple ValleyTeacher Share by Email Share on LinkedIn Share on Twitter Read more
Cashier - *Apple* Blossom Mall - JCPenney (...
Cashier - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Blossom Mall Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.