-- JaMVMImpl.mesa -- Pilot version -- Original version by Martin Newell, February 1979 -- Updated June 12, 1979 4:42 PM by MN -- Last changed by Bill Paxton, November 5, 1982 9:45 am DIRECTORY JaMBasic, JaMVM, Inline, Space, RTOS; JaMVMImpl: MONITOR IMPORTS JaMVM, Inline, RTOS EXPORTS JaMVM = { OPEN JaMBasic; -- Globals Offs: TYPE = [0..1]; Ptr: TYPE = LONG POINTER; segment: Ptr ← NIL; -- to base of current chunk of storage size: LONG CARDINAL ← 0; -- size of current segment words: LONG CARDINAL ← 0; -- number of words allocated from this chunk offset: CARDINAL ← 0; -- Procedures WordsForPages: PROC[p: CARDINAL] RETURNS[LONG CARDINAL] = INLINE { RETURN[Inline.LongMult[p,Space.wordsPerPage]] }; PagesForWords: PROC[w: LONG CARDINAL] RETURNS[CARDINAL] = INLINE { RETURN[Inline.LongDiv[w + Space.wordsPerPage - 1, Space.wordsPerPage]] }; Expand: PROC [atleast: LONG CARDINAL] = { want: CARDINAL ← PagesForWords[atleast]; pages: CARDINAL ← 4*((MAX[want,64]+1)/4); -- round up to multiple of 4 size ← WordsForPages[pages]; -- create a space to the hold monster segment ← RTOS.GetDataPagesFromNewSpace[nPages: pages]; words ← 0; offset ← 0; }; AllocWords: ENTRY PROC[n: LONG CARDINAL] RETURNS[Ptr] = { DO ptr: Ptr; IF offset > 0 THEN { words ← words + 1; offset ← 0 }; ptr ← segment + words; words ← words + n; IF words >= size THEN { Expand[n]; LOOP }; RETURN[ptr]; ENDLOOP; }; AllocChars: ENTRY PROC[n: CARDINAL] RETURNS[Ptr,Offs] = { DO ptr: Ptr ← segment + words; offs: Offs ← offset; frac: CARDINAL ← offs + n MOD 2; words ← words + n/2 + frac/2; -- mind overflow! offset ← frac MOD 2; IF words >= size THEN { Expand[n/2 + frac/2]; LOOP }; RETURN[ptr,offs]; ENDLOOP; }; AllocString: PUBLIC PROC[length: StringLength] RETURNS[string Object] = { string: string Object ← [L,string[length: length, text: , offset: ]]; [string.text,string.offset] ← AllocChars[length]; RETURN[string]; }; AllocArray: PUBLIC PROC[length: CARDINAL] RETURNS[array Object] = { array: array Object ← [L,array[length: length, base: ]]; array.base ← AllocWords[Inline.LongMult[length,SIZE[Object]]]; RETURN[array]; }; AllocTuples: PROC[size: CARDINAL] RETURNS[beg,end: TuplePtr] = { words: LONG CARDINAL ← Inline.LongMult[size,SIZE[Tuple]]; beg ← AllocWords[words]; end ← beg + words; RETURN[beg,end]; }; AllocDict: PUBLIC PROC[size: CARDINAL] RETURNS[dict Object] = { dict: dict Object ← [L,dict[AllocWords[SIZE[DictBody]]]]; dd: DictBody ← [curlen: 0, maxlen: 0, size: size, beg: , end: , curatt: 0, attach: [L,array[0,NIL]]]; [dd.beg,dd.end] ← AllocTuples[size]; JaMVM.PutDict[dict,dd]; RETURN[dict]; }; CopyArray: PUBLIC PROC[src,dst: array Object] = { count: CARDINAL ← MIN[src.length,dst.length]; -- number of objects to copy sptr: LONG POINTER ← src.base; dptr: LONG POINTER ← dst.base; words: LONG CARDINAL ← Inline.LongMult[count,SIZE[Object]]; chunk: CARDINAL = (LAST[CARDINAL]/SIZE[Object])*SIZE[Object]; WHILE words>0 DO w: CARDINAL ← Inline.LowHalf[MIN[words,chunk]]; Inline.LongCOPY[from: sptr, nwords: w, to: dptr]; sptr ← sptr + w; dptr ← dptr + w; words ← words - w; ENDLOOP; }; GetText: PUBLIC PROC[string: string Object, text: LONG STRING] = { count: CARDINAL ← MIN[string.length,text.maxlength]; stext: LONG POINTER TO TextBody ← string.text; soffs: CARDINAL ← string.offset; FOR i: CARDINAL IN[0..count) DO text[i] ← stext[soffs+i] ENDLOOP; text.length ← count; }; PutText: PUBLIC PROC[string: string Object, text: LONG STRING] = { count: CARDINAL ← MIN[string.length,text.length]; stext: LONG POINTER TO TextBody ← string.text; soffs: CARDINAL ← string.offset; FOR i: CARDINAL IN[0..count) DO stext[soffs+i] ← text[i] ENDLOOP; }; CopyString: PUBLIC PROC[src,dst: string Object] = { count: CARDINAL ← MIN[src.length,dst.length]; -- number of chars to copy stext: LONG POINTER TO TextBody ← src.text; dtext: LONG POINTER TO TextBody ← dst.text; soffs: CARDINAL ← src.offset; doffs: CARDINAL ← dst.offset; FOR i: CARDINAL IN[0..count) DO dtext[doffs+i] ← stext[soffs+i] ENDLOOP; }; rootInfo: LONG POINTER TO Root ← NIL; GetRoot: PUBLIC PROC[root: LONG POINTER TO Root] = { root↑ ← rootInfo↑ }; PutRoot: PUBLIC PROC[root: LONG POINTER TO Root] = { rootInfo↑ ← root↑ }; Start: PUBLIC PROC = { rootInfo ← AllocWords[SIZE[Root]]; }; }.