mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-29 05:49:19 +00:00
4497 lines
128 KiB
Plaintext
4497 lines
128 KiB
Plaintext
;
|
||
; File: ScriptMgrUtilNum.a (formerly SMgrUtilNum.a)
|
||
;
|
||
; Contains: Script Manager formatted number routines
|
||
;
|
||
; Written by: DRS daan Strebe
|
||
; MED Mark Davis
|
||
; LDC Lee Collins
|
||
; PKE Peter Edberg
|
||
;
|
||
; Copyright: © 1987-1992 by Apple Computer, Inc. All rights reserved.
|
||
;
|
||
; This file is used in these builds: ROM, disk
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM3> 11/6/92 SWC Changed PackMacs.a->Packages.a.
|
||
; <8> 4/30/92 FM Remove obsolete conditionals: smgrUsesStdExit, smgrSysVers
|
||
; <7> 9/14/90 BG Removed <6>. 040s are now behaving more reliably.
|
||
; <6> 7/17/90 BG Added EclipseNOPs for flakey 040s.
|
||
; <5> 4/16/90 PKE Use smgrSysVers and smgrROMVers symbols instead of buildLevel to
|
||
; control conditionalization.
|
||
; <4> 4/10/90 PKE Deleted conditionalized definitions of forRom, SysVers, and
|
||
; TestScriptManager. Deleted import of GetSMgrCore macro! Fixed
|
||
; tabs. Used new smgrUseStdExit symbol instead of buildLevel where
|
||
; appropriate.
|
||
; <3> 3/4/90 PKE Changed _UprText to _UpperText to match new Traps.a.
|
||
; <2> 2/22/90 PKE Replaced obsolete _LwrStringToUpr opword with _UprText. Updated
|
||
; header to BBS format.
|
||
; <1> 12/18/89 CCH Adding for the first time into BBS. Changed include 'inc.sum.a'
|
||
; to load 'StandardEqu.d'. Updated file name references.
|
||
;
|
||
; (BBS versions above, EASE versions below:)
|
||
; <2.2> 8/26/89 PKE Cleaned up conditionals, changing newItl2Tables to buildLevel >=
|
||
; 1.
|
||
; <2.1> 8/22/89 SES Removed references to nFiles.
|
||
; <2.0> 6/30/89 PKE NEEDED FOR AURORA: Use new LwrString for localizable upper-
|
||
; casing (!) instead of UprString; change to use internal vectors
|
||
; for ROM version only. (First item is from code review, second
|
||
; item is only a change for 7.0).
|
||
; <1.9> 6/23/89 PKE Skip definition of buildLevel (done in ScriptPriv.a).
|
||
; <1.8> 5/22/89 PKE (Esprit needs this too): 1) Fix FormatStr2X to correct
|
||
; best-guess handling of negative numbers that don't match the
|
||
; format string (was broken by Altair changes). 2) Fix
|
||
; ConvertToString so that FormatX2Str handles a 0 value correctly
|
||
; in a format with an exponent (BRC #39590). 3) Change
|
||
; CheckForDigits and FormatStr2X so that when trying to match a
|
||
; number string to a zero format, non-zero digits are not accepted
|
||
; until after an exponent (fixes BRC #41209). 4) Fix Str2Format to
|
||
; impose tighter restrictions on format strings: it now disallows
|
||
; any format with preDig+postDig=0, unless it is just a literal
|
||
; with no decimal pt., exponent, or percent sign (fixes BRC
|
||
; #47210, 47211, 47212). 5) Fix FormatStr2X & FormatX2Str to check
|
||
; for invalid formats detected by Str2Format. 6) Fix
|
||
; CheckForm/SendItem so Format2Str returns correct positions (BRC
|
||
; #46877). NOTE: Should have more limit checking.
|
||
; <1.7> 2/21/89 PKE Replaced with RomProj version, which already had system and Rom
|
||
; sources merged.
|
||
; (EASE ROMproj history below)
|
||
; <1.5> 2/21/89 PKE Fix up includes: always use include 'inc.sum.a'. Fix bugs caused
|
||
; by old use of a5 as a temp register; this caused problems with
|
||
; the new method of getting case conversion tables out of itl2.
|
||
; For example, MatchingBlocks saves/restores a5, and uses it in
|
||
; between as a temp reg; but while a5 is altered, it calls
|
||
; MatchingSubstring, which calls CharComp, which calls UprString,
|
||
; which NOW calls IUGetIntl, which calls IntlScript, which depends
|
||
; on the a5 world. Still need to remove a5 use in xFormX2Str,
|
||
; which doesn't indirectly call UprString, but which should be
|
||
; fixed anyway. ALso, xFormStr2X unnecessarily saves a5.
|
||
; <1.4> 2/14/89 PKE Updated to use MPW 3.0 final ScriptEqu.a equate names
|
||
; <1.3> 2/3/89 PKE Merged with current system sources (CCH's 01/16/1989 merge of
|
||
; 6.0.3 and 7.0 sources, done in RES.sys:smgr)
|
||
; <1.2> 11/14/88 PKE Synchronize EASE and Projector
|
||
; <1.1> 11/11/88 CCH Fixed Header.
|
||
; <1.0> 11/9/88 CCH Adding to EASE.
|
||
; (old EASE ROMproj history below)
|
||
; <1.7> 10/27/88 LDC Mods by Carl Hewitt and Brian McGhie in the process of putting
|
||
; Script Manager in ROM
|
||
; (EASE SYSproj history below)
|
||
; <1.6> 2/14/89 PKE Updated to use MPW 3.0 final ScriptEqu.a equates
|
||
; <1.5> 1/31/89 PKE One more "SysVers >= $700" conditionalization fixup
|
||
; <1.4> 1/31/89 PKE Use "SysVers >= $700" to conditionalize BEQ.S vs BEQ somewhere
|
||
; <1.3> 1/31/89 PKE Fixed up some of the "SysVers >= $700" conditionalization
|
||
; <1.2> 1/17/89 CCH Merged changes from 6.0.3.
|
||
; <1.1> 1/16/89 CCH Merged 6.0.3 final sources into 7.0.
|
||
; <1.0> 11/16/88 CCH Added to EASE.
|
||
; (pre-EASE history below)
|
||
; 9/21/88 ldc fixed bug #30677 and 30680, checking for multiple decimals and
|
||
; spurious chars
|
||
; 9/19/88 fixed bug #29602, non acceptance of #.##e+# format
|
||
; 9/8/88 ldc fixed 30678 (failure to detect overflow) in FormatStr2X and
|
||
; 33761 (confusion of overflow with nan)
|
||
; 9/7/88 ldc fixed failure to detect minus zero cf bug # 30675 and failure to
|
||
; detect empty format string (c.f. bug ddm #29008)
|
||
; 6/17/88 ldc Vectorized internal procs
|
||
; 5/19/88 ldc added standard exits
|
||
; * changes above are for ROM or buildLevel >= 2 *
|
||
; 4/14/88 ldc fix to problem with empty string not returning nan; changed
|
||
; failure to match literal string to return NAN(17), instead of
|
||
; fSpuriousChars ** Changes for ROM or buildLevel 2: **
|
||
; 4/4/88 ldc Changed NumFormatString record to FormatStringPriv
|
||
; 4/4/88 ldc fixed problem with random garbage after booting in Format2Str
|
||
; 3/31/88 ldc fixed FormatStr2X to allow output of 1 when positive format
|
||
; input is literal string containing no digits e.g., 'number' => 1
|
||
; 3/30/88 ldc fixed problem with not being able to output literal only format
|
||
; strings, e.g. 'zero', in FormatX2Str
|
||
; 3/28/88 ldc Fixed random bug caused by non initialization of length of
|
||
; outString in Format2Str
|
||
; 3/25/88 ldc added code in FormatX2Str to fix problem will excess clipping of
|
||
; predecimal leaders when non-leaders are present (#000.0 + 1.0 ->
|
||
; 001.0, not 1.0). Also compacted calls to DoSendChar in
|
||
; AppendSymbol
|
||
; 3/18/88 ldc found two more missing offsets to NumberParts.data
|
||
; 3/18/88 ldc Fixed bra.s to looptest
|
||
; 3/17/88 med IsSubstring: Since dan is using limits, not counts, a limit of
|
||
; zero means one character
|
||
; 3/17/88 ldc CheckExp: hanged because this was getting the wrong address
|
||
; 3/16/88 ldc Added boolean parameter "ignoreCase" to MatchingSubString
|
||
; 3/15/88 ldc Placed call UprString within CharComp
|
||
; 3/14/88 ldc Cleaned up after adding version to Number Parts table.
|
||
; 3/4/88 ldc added UprString to allow case insensitivity
|
||
; 2/25/88 med/ldc Fixed alternate digits address error and bad index.
|
||
; 2/25/88 med/ldc Fixed failure to detect overflow with ".##" + 345.0
|
||
; 2/25/88 drs also "bettered" the display zero paradigm
|
||
; 2/25/88 drs Fixed both open bugs in one fell swoop; "^.#" + 0 => "*.", but
|
||
; "*." not accepted on input, "#;#.#E+#'DB'" + 3.E+0DB => 3
|
||
; 2/24/88 ldc added 'fBestGuess' to flag case when no exact match is found
|
||
; 2/23/88 ldc replaced #1 with #fFormatOK
|
||
; 2/23/88 ldc fixed xyz -> nan,error; -xyz -> nan,noError
|
||
; 2/22/88 ldc removed nested LINK and UNLK in FormatStr2X
|
||
; 2/19/88 ldc Added debugging macros for symbol generation
|
||
; 2/8/88 med Fixed leaders to print correctly, not "^^^" => "***"
|
||
; 2/8/88 med Better bounds checking in SendChar
|
||
; 2/8/88 med Garbage input partially caught (drs)
|
||
; 2/8/88 med Special SANE values not caught (drs)
|
||
; 2/7/88 med Fixed embedded escaped characters in Format2Str.
|
||
; 2/7/88 med Changed TranslateText to use two-byte char for catching escaped
|
||
; characters
|
||
; 2/7/88 med Got quotes to work properly on Format2Str!
|
||
; 2/7/88 med misc fixes, some optimizations; lot of code transposition
|
||
; 2/7/88 med formCount is a byte
|
||
; 2/7/88 med Added some formatting with macros
|
||
; 1/25/88 med Dan added comments & fixed three minor bugs:
|
||
; "#.##'CR';#.##'DB'" + "2.1DB" didn't yield -2.1
|
||
; "##E#,###" + 1E1234 didn't yield "1E1,234"
|
||
; "#.#" + "2." ≠> 2.0
|
||
; 1/7/88 med Added inversion for odd cases
|
||
; 12/16/87 med Included Dan’s assemblyized versions, for comments see pascal
|
||
; version
|
||
;___________________________________________________________________________________________________
|
||
; To Do (old):
|
||
; Format Open features:
|
||
; Better alternate numbers selection.
|
||
; Leaders should act also as trailers: "###^^^.^^^###" + 3.4 => ***3.4***
|
||
; Less strict pattern-matching.
|
||
; General code review & optimization.
|
||
; E.g. Axe the addendum string in Translate to text, just append to dest string.
|
||
; Issue: On input, unquoteds get turned into quoteds
|
||
; What to do about '-' in the format string.
|
||
;___________________________________________________________________________________________________
|
||
|
||
STRING AsIs
|
||
|
||
MACRO
|
||
CheckDebug &thisProc
|
||
if testScriptManager then
|
||
dc.b &thisProc
|
||
endif
|
||
ENDM
|
||
|
||
load 'StandardEqu.d'
|
||
include 'ScriptPriv.a'
|
||
include 'SANEMacs.a'
|
||
include 'Packages.a'
|
||
|
||
IMPORT StdUnlink
|
||
|
||
EXPORT xStr2Form,xForm2Str,xFormX2Str,xFormStr2X
|
||
|
||
; internal routine exports <6/18/88ldc>
|
||
EXPORT AppendSymbol
|
||
EXPORT ConvertToString
|
||
EXPORT ExpHandling
|
||
EXPORT ExpMatching
|
||
EXPORT CheckForDigits
|
||
EXPORT MatchingSubstring
|
||
EXPORT Cond
|
||
EXPORT CheckForm
|
||
EXPORT TackOnExp
|
||
EXPORT MakeExp
|
||
EXPORT CheckPartsIntegrity
|
||
EXPORT RetrieveChar
|
||
EXPORT IsSubstring
|
||
|
||
;============================================================
|
||
macro
|
||
comp0 &a,&b,&c
|
||
if &substr(&a,1,1)<>'#' goto +.normal
|
||
if &eval(&substr(&a,2,&len(&a)-1))<>0 goto +.normal
|
||
tst&c &b
|
||
goto +.end
|
||
.normal:
|
||
cmp&c &a,&b
|
||
.end:
|
||
endMacro
|
||
|
||
macro
|
||
compw &a,&b
|
||
comp0 &a,&b,.w
|
||
endMacro
|
||
|
||
macro
|
||
compl &a,&b
|
||
comp0 &a,&b,.l
|
||
endMacro
|
||
|
||
macro
|
||
compb &a,&b
|
||
comp0 &a,&b,.b
|
||
endMacro
|
||
|
||
|
||
|
||
;============================================================
|
||
; Routine CharComp(char1,char2: HighChar): Boolean
|
||
;case insensitive comparison of two characters
|
||
;<3/15/88ldc> added CharComp
|
||
;
|
||
; trashes a0, d0, d1
|
||
; calls _UprString (6.0.4 & earlier)/_LwrString (new ROMs & 7.0)
|
||
;
|
||
; NOTE: UprString (called by CharComp) now depends on the a5 world,
|
||
; so don't muck around with a5 before calling CharComp! <02/21/89 pke>
|
||
; Actually, UprString is again independent of a5 world, but now we're
|
||
; using LwrString instead, which DOES depend on a5 world. <06/30/89 pke>
|
||
;
|
||
CharCompFrame record {oldA6},decrement
|
||
equal ds.w 1 ; return value
|
||
args equ *
|
||
char1 ds.w 1 ; char
|
||
char2 ds.w 1 ; char
|
||
argSize equ args-*
|
||
returnAdr ds.l 1
|
||
oldA6 ds.l 1
|
||
locals equ *
|
||
endr
|
||
;-------------------------------
|
||
|
||
CharComp proc
|
||
with CharCompFrame
|
||
link A6, #locals
|
||
|
||
lea char1(a6), a0 ; UprString uses a0 for string ptr
|
||
move.w #2, d0 ; apply UprString to one char
|
||
|
||
_UpperText ; _LwrString with smUpper function <3>
|
||
move.w (a0), d1
|
||
|
||
lea char2(a6), a0
|
||
move.w #2, d0 ; apply UprString to one byte
|
||
|
||
_UpperText ; _LwrString with smUpper function <3>
|
||
cmp.w (a0), d1
|
||
|
||
seq equal(a6)
|
||
|
||
move #argSize, d0 ; for StdUnlink
|
||
bra StdUnlink ; standard exit
|
||
|
||
CheckDebug 'CHARCOMP'
|
||
endwith
|
||
endp
|
||
|
||
;============================================================
|
||
; NextFormatClass
|
||
;
|
||
; trashes d0
|
||
; calls --
|
||
;
|
||
NextFormatClass proc
|
||
|
||
EXT.W D0
|
||
ADDQ.W #1,D0
|
||
compw #3,D0
|
||
BNE.S @L1
|
||
MOVEQ.L #0,D0
|
||
@L1:
|
||
RTS
|
||
endp
|
||
|
||
|
||
;============================================================
|
||
;<9/8/88ldc>
|
||
; Function GetSANEClass
|
||
; Gets SANE number class for extended
|
||
; input:
|
||
; a1 = ptr to extended
|
||
; output:
|
||
; d0 = class
|
||
; uses:
|
||
; a0
|
||
;<9/8/88ldc> SANE number classes
|
||
negZero equ $fffc ; -4 ie negative zero sane number class <9/7/88ldc>
|
||
posQNan equ $0002 ; positive quiet NAN
|
||
negQNan equ $fffe ; negative quiet NAN
|
||
posSNan equ $0001 ; positive signalling NAN
|
||
negSNan equ $ffff ; negative signalling NAN
|
||
posInf equ $0003 ; positive infinity
|
||
negInf equ $fffd ; negative infinity
|
||
posDeNorm equ $0005 ; positive denormalized
|
||
negDeNorm equ $fffb ; negative denormalized
|
||
|
||
GetSANEClass proc
|
||
clr.w -(sp) ; word storage
|
||
movea.l sp, a0 ; old stack position
|
||
move.l a1, -(sp) ; push x
|
||
move.l a0, -(sp) ; storage for temp integer
|
||
FClassX ; use SANE to get class
|
||
move.w (sp)+, d0 ; return value is now on top
|
||
rts
|
||
endp
|
||
;============================================================
|
||
|
||
IF 1 THEN ; unfinished--don't use yet <2/7/88med>
|
||
SendByte proc
|
||
; input a0 @StrPtr (length is actually max value)
|
||
; a1 @position for next char (1..254)
|
||
; d0 byte to add
|
||
; output d0 result code
|
||
; uses d1,d2
|
||
; function add byte to string. Omit nulls, and check for overflow
|
||
|
||
move.b d0,d1 ; null?
|
||
beq.s @SendOk ; skip
|
||
move.l #fFormatOverflow,d0 ; default result = bad
|
||
move.w (a1),d2 ; get next position (1.255)
|
||
cmp.b (a0),d2 ; compare max length
|
||
bhs.s @SendExit ; too big, bail
|
||
move.b d1,0(a0,d2.w) ; set byte
|
||
add.w #1,(a1) ; bump position
|
||
@SendOk
|
||
move.l #fFormatOK,d0 ; return ok
|
||
@SendExit
|
||
rts
|
||
endProc
|
||
|
||
;============================================================
|
||
SendCharRev0 proc
|
||
; input a0 @StrPtr (length is actually max value
|
||
; a1 @position for next char (1..254)
|
||
; d0 word to add
|
||
; output d0 result code
|
||
|
||
export SendChar0
|
||
ror.w #8,d0 ; exchange top and bottom bytes
|
||
|
||
SendChar0
|
||
move.w d0,-(sp) ; stash whole char
|
||
move.b (sp),d0 ; get top byte
|
||
bsr.s SendByte ; send it (if it is too far, next will be too)
|
||
move.w (sp)+,d0 ; get bottom byte (don't care about top)
|
||
bsr.s SendByte ; send it
|
||
rts
|
||
endProc
|
||
|
||
SendCharRev proc
|
||
export SendChar
|
||
|
||
topByte equ 12
|
||
botByte equ 13
|
||
textPtr equ 8
|
||
textLen equ 4
|
||
argBytes equ 10
|
||
|
||
MOVE.B topByte(A7),D0
|
||
MOVE.B botByte(A7),topByte(A7)
|
||
MOVE.B D0,botByte(A7)
|
||
; drop through
|
||
|
||
; discard this mess and use a register interface someday
|
||
|
||
; SendChar
|
||
; trashes a0-a1,d0,d2,d1 (in SendByte)
|
||
SendChar
|
||
move.l (a7)+,d2 ; return address
|
||
move.l (a7)+,a1 ; @position
|
||
move.l (a7)+,a0 ; @textPtr
|
||
move.w (a7)+,d0 ; word to add
|
||
move.l d2,-(a7) ; restore return
|
||
bsr.s SendChar0 ; do real routine
|
||
move.w d0,4(a7) ; set return
|
||
rts
|
||
endProc
|
||
;============================================================
|
||
ELSE
|
||
;============================================================
|
||
; old version was here
|
||
ENDIF
|
||
|
||
;------------------------------------------------------------
|
||
Str2FormFrame record {oldA61},decrement
|
||
returnValue1 ds.w 1 ; INTEGER
|
||
argFrameT1 EQU *
|
||
inString ds.l 1 ; VAR str255
|
||
partsTable ds.l 1 ; VAR NumberParts
|
||
outString ds.l 1 ; VAR NumFormatString
|
||
selector1 ds.l 1
|
||
argFrame1 EQU argFrameT1-*
|
||
|
||
return1 ds.l 1
|
||
oldA61 ds.l 1
|
||
|
||
formCount ds.b 1 ; formatClass
|
||
going ds.b 1 ; BOOLEAN
|
||
c ds.w 1 ; wideChar
|
||
outIndex ds.w 1 ; INTEGER
|
||
inIndex ds.w 1 ; INTEGER
|
||
res ds.w 1 ; INTEGER
|
||
thisCode ds.w 1 ; INTEGER
|
||
altNumFlag ds.b 1 ; BOOLEAN
|
||
ALIGN 2
|
||
currentFlags ds.w 1 ; BitPack
|
||
localFrame1 EQU *
|
||
ENDR
|
||
|
||
;============================================================
|
||
InUnquoteds proc
|
||
|
||
; moved in-line
|
||
|
||
endp
|
||
|
||
;============================================================
|
||
; RetrieveChar
|
||
;
|
||
; trashes a0,d0,d1
|
||
; uses/restores a2,a3,a4,d7
|
||
; calls _CharByte (may trash a0-a1,d0-d2)
|
||
;
|
||
RetrieveChar proc
|
||
|
||
;------------------------------------------------------------
|
||
retrieveCharFrame record {oldA62},decrement
|
||
returnValue2 ds.w 1 ; BOOLEAN
|
||
argFrameT2 EQU *
|
||
index ds.l 1 ; VAR INTEGER
|
||
oldA6f2 ds.l 1
|
||
argFrame2 EQU argFrameT2-*
|
||
|
||
return2 ds.l 1
|
||
oldA62 ds.l 1
|
||
k ds.w 1
|
||
localFrame2 EQU *
|
||
ENDR
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
localRegs reg D7/A2-A4
|
||
indexR EQU A3
|
||
ff EQU A4
|
||
inStringR EQU A2
|
||
kR EQU D7
|
||
|
||
;============================================================
|
||
WITH Str2FormFrame,retrieveCharFrame
|
||
|
||
;pull the next character our of the input string, whether it be a
|
||
;single-byte character or a two-byte character
|
||
|
||
LINK A6,#localFrame2
|
||
MOVEM.L localRegs,-(A7)
|
||
MOVEA.L index(A6),indexR
|
||
MOVEA.L oldA6f2(A6),ff
|
||
CLR.W returnValue2(A6) ;default on null--the low byte usually is anyway
|
||
MOVEA.L inString(ff),inStringR ;we use inString fairly often
|
||
CLR.W D0
|
||
MOVE.B (inStringR),D0
|
||
compw (indexR),D0 ;check if we have source chars left
|
||
BLT.S @out
|
||
CLR.W -(A7) ;we need to check how many bytes in the next char
|
||
PEA 1(inStringR) ;address of first byte
|
||
MOVE.W (indexR),D0 ;index into string
|
||
SUBQ.W #1,D0 ;minus 1 for 0 based
|
||
MOVE.W D0,-(A7)
|
||
_CharByte
|
||
MOVE.W (A7)+,kR ;0 designates single byte char
|
||
BNE.S @twoByte
|
||
MOVE.W (indexR),D0 ;get the current character
|
||
CLR.W D1
|
||
MOVE.B 0(inStringR,D0.W),D1
|
||
MOVE.W D1,returnValue2(A6) ;put it in the return position
|
||
ADDQ.W #1,(indexR) ;and increment the index
|
||
BRA.S @out
|
||
@twoByte:
|
||
BPL.S @outOfSync ;positive CharByte means middle of two-byte char
|
||
MOVE.W (indexR),D0 ;make sure that if it's two byte then÷
|
||
CMP.B (inStringR),D0 ;there actually is a second byte
|
||
BGE.S @outOfSync
|
||
MOVE.B 0(inStringR,D0.W),returnValue2(A6) ;place the bytes
|
||
MOVE.B 1(inStringR,D0.W),(returnValue2+1)(A6)
|
||
ADDQ.W #2,(indexR) ;and increment index
|
||
BRA.S @out
|
||
@outOfSync:
|
||
MOVE.W #fOutOfSynch,returnValue1(ff) ;no integrity in input string
|
||
@out:
|
||
MOVEM.L (A7)+,localRegs
|
||
|
||
move #argFrame2, d0 ; for StdUnlink
|
||
bra StdUnlink ; standard exit
|
||
|
||
CheckDebug 'RETRIEVE'
|
||
|
||
ENDWITH
|
||
endp
|
||
|
||
;------------------------------------------------------------
|
||
CheckPartsIntegrityFrame record {oldA62},decrement
|
||
returnValue2 ds.w 1 ; BOOLEAN
|
||
argFrameT2 EQU *
|
||
oldA6f2 ds.l 1
|
||
argFrame2 EQU argFrameT2-*
|
||
|
||
return2 ds.l 1
|
||
oldA62 ds.l 1
|
||
temp ds.w 1 ; INTEGER
|
||
j ds.w 1 ; INTEGER
|
||
i ds.w 1 ; INTEGER
|
||
localFrame2 EQU *
|
||
ENDR
|
||
|
||
;============================================================
|
||
; CheckExp
|
||
;
|
||
; trashes a0,d0
|
||
; uses/restores a2,a3,a4,d6,d7
|
||
;
|
||
CheckExp proc
|
||
|
||
;------------------------------------------------------------
|
||
CheckExpFrame record {oldA63},decrement
|
||
argFrameT3 EQU *
|
||
exp ds.l 1 ; VAR wideCharArr
|
||
oldA6f3 ds.l 1
|
||
argFrame3 EQU argFrameT3-*
|
||
|
||
return3 ds.l 1
|
||
oldA63 ds.l 1
|
||
x ds.w 1 ; INTEGER
|
||
i ds.w 1 ; INTEGER
|
||
localFrame3 EQU *
|
||
ENDR
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
localRegs reg D6/D7/A2-A4
|
||
ff EQU A2
|
||
ff1 EQU A3
|
||
partsTableR EQU A4
|
||
xR EQU D6
|
||
iR EQU D7
|
||
|
||
;============================================================
|
||
WITH Str2FormFrame,CheckPartsIntegrityFrame,CheckExpFrame
|
||
|
||
;make sure that the first character of the exponent doesn't coincide with…
|
||
;…any other first character
|
||
|
||
LINK A6,#localFrame3
|
||
MOVEM.L localRegs,-(A7)
|
||
MOVEA.L oldA6f3(A6),ff ;load up all the usuals
|
||
MOVEA.L oldA6f2(ff),ff1
|
||
|
||
; MOVEA.L (partsTable+NumberParts.data)(ff1),partsTableR
|
||
;<3/17/88ldc> changed because this was getting the wrong address
|
||
MOVEA.L partsTable(ff1),partsTableR
|
||
|
||
ADDA.W #NumberParts.data, partsTableR
|
||
MOVEA.L exp(A6),A0 ;examine the exponent
|
||
compw #0,WideCharArr.size(A0) ;does it have any characters in it? <2/7/88med>
|
||
blt.s @out ; zero test now <2/7/88med>
|
||
MOVE.W WideCharArr.data(A0),xR
|
||
BEQ.S @out ;just to be sure
|
||
MOVE.W #(tokMaxSymbols-1),iR ;check against the entire parts table
|
||
@expLoop:
|
||
compw (partsTableR)+,xR
|
||
DBEQ iR,@expLoop
|
||
BNE.S @out ;no match; we just ran out of data
|
||
CLR.B returnValue2(ff) ;we actually matched, which is an error
|
||
@out:
|
||
MOVEM.L (A7)+,localRegs
|
||
|
||
move #argFrame3, d0 ; for StdUnlink
|
||
bra StdUnlink ; standard exit
|
||
|
||
CheckDebug 'CHECKEXP'
|
||
ENDWITH
|
||
endp
|
||
|
||
;============================================================
|
||
; CheckPartsIntegrity
|
||
;
|
||
; trashes a0,d0,d1,d2
|
||
; uses/restores a4,d5-d7
|
||
; calls CheckExp, which trashes a0,d0
|
||
;
|
||
CheckPartsIntegrity proc
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
localRegs reg D5-D7/A4
|
||
partsTableR EQU A4
|
||
iR EQU D7
|
||
tempR EQU D5
|
||
jR EQU D6
|
||
|
||
;============================================================
|
||
WITH Str2FormFrame,CheckPartsIntegrityFrame,NumberParts
|
||
|
||
;Test the internal integrity of the parts table by making sure that
|
||
;the first digit of any exponent string doesn't coincide with any other
|
||
;entries except other exponent strings; making sure that no other
|
||
;entries coincide with any other entries except for left vs. right
|
||
;quote marks and leadPlace vs. leader
|
||
|
||
LINK A6,#localFrame2
|
||
MOVEM.L localRegs,-(A7)
|
||
MOVEA.L oldA6f2(A6),A0
|
||
MOVEA.L partsTable(A0),partsTableR
|
||
ST returnValue2(A6) ;be optimistic for once and assume no problem
|
||
|
||
; check the version
|
||
cmp.w #curNumberPartsVersion,version(partsTableR) ; good version?
|
||
bne @ReturnBadParts
|
||
|
||
; continue with check
|
||
|
||
MOVEQ #tokLeftQuote,iR ;i is the loop counter
|
||
BRA.S @endI
|
||
@forI:
|
||
MOVE.W iR,D0 ;collect the current sample
|
||
ADD.W D0,D0
|
||
MOVE.W (-(tokLeftQuote*2)+data)(partsTableR,D0.W),tempR
|
||
BEQ.S @contI ;ignore it if it's empty…
|
||
MOVE.W iR,jR ;…otherwise check against the rest of the table
|
||
ADDQ.W #1,jR ;starting 1 after self
|
||
BRA.S @endJ
|
||
@startJ:
|
||
MOVE.W jR,D0 ;make sure we have no duplicate entries
|
||
ADD.W D0,D0
|
||
compw (-(tokLeftQuote*2)+data)(partsTableR,D0.W),tempR
|
||
BNE.S @contJ ;we got a match
|
||
compw #tokLeadPlacer,iR ;but if it's leadPlacer vs. leader, then fine
|
||
SEQ D0
|
||
compw #tokLeader,jR
|
||
SEQ D1
|
||
AND.B D1,D0
|
||
compw #tokLeftQuote,iR ;or if it's leftQuote vs. rightQuote then fine
|
||
SEQ D1
|
||
compw #tokRightQuote,jR
|
||
SEQ D2
|
||
AND.B D2,D1
|
||
OR.B D1,D0
|
||
;; BNE.S @contJ
|
||
;; SF returnValue2(A6) ;it was neither, so bad break
|
||
beq.s @ReturnBadParts ; bail with bad value
|
||
@contJ:
|
||
ADDQ.W #1,jR ;on to the next
|
||
@endJ:
|
||
compw #tokMaxSymbols,jR ;but are we done?
|
||
BLE.S @startJ
|
||
@contI:
|
||
ADDQ.W #1,iR ;now increment the outer loop counter
|
||
@endI:
|
||
compw #(tokMaxSymbols-1),iR ;and check for done
|
||
BLE.S @forI
|
||
PEA PePlus(partsTableR) ;check the exponents
|
||
MOVE.L A6,-(A7)
|
||
JSR CheckExp
|
||
PEA PeMinus(partsTableR)
|
||
MOVE.L A6,-(A7)
|
||
JSR CheckExp
|
||
;<1/29/88drs> Changed 8 lines to fix what I'm sure was a bug but never showed up
|
||
LEA NumberParts.data(partsTableR),a0 ; use a0 as temp <2/25/88med>
|
||
MOVE.W #(tokMaxSymbols),iR ;we also need to make sure that…
|
||
@ccLoop: ;there are no control codes in the table
|
||
SUBQ.W #1,iR ;loop the loop
|
||
BLT.S @ccEnd
|
||
MOVE.W (a0)+,D0 ; use a0 as temp <2/25/88med>
|
||
BEQ.S @ccLoop ;null character is legal
|
||
compb #(tokMaxSymbols+1),D0 ;control char is not legal
|
||
BHS.S @ccLoop
|
||
bra.s @ReturnBadParts ; bail with bad value
|
||
;; SF returnValue2(A6) ;reflect your disappointment
|
||
@ccEnd:
|
||
cmp.w #9,altNumTable.size(partsTableR) ; right size? <2-25-88med/ldc>
|
||
beq.s @ccRealEnd ; escape if good <2-25-88med/ldc>
|
||
@ReturnBadParts
|
||
SF returnValue2(A6) ;reflect your disappointment <2-25-88med/ldc>
|
||
@ccRealEnd:
|
||
MOVEM.L (A7)+,localRegs
|
||
UNLK A6
|
||
MOVE.L (A7)+,(A7)
|
||
RTS
|
||
|
||
CheckDebug 'CHECKPAR'
|
||
ENDWITH
|
||
endp
|
||
|
||
;------------------------------------------------------------
|
||
MakeExpFrame record {oldA62},decrement
|
||
returnValue2 ds.w 1 ; BOOLEAN
|
||
argFrameT2 EQU *
|
||
exp ds.l 1 ; VAR WideCharArr
|
||
expOrd ds.w 1 ; INTEGER
|
||
expChar ds.w 1 ; CHAR
|
||
oldA6f2 ds.l 1
|
||
argFrame2 EQU argFrameT2-*
|
||
|
||
return2 ds.l 1
|
||
oldA62 ds.l 1
|
||
localFrame2 EQU *
|
||
ENDR
|
||
|
||
;============================================================
|
||
; IsSubstring
|
||
;
|
||
; trashes a0,d0,d1 (maybe a1,d2)
|
||
; uses/restores a3,a4,d7
|
||
; calls RetrieveChar, which trashes a0,d0,d1 (maybe a1,d2)
|
||
;
|
||
IsSubstring proc
|
||
|
||
;------------------------------------------------------------
|
||
isSubStringFrame record {oldA63},decrement
|
||
returnValue3 ds.w 1 ; BOOLEAN
|
||
argFrameT3 EQU *
|
||
oldA6f3 ds.l 1
|
||
argFrame3 EQU argFrameT3-*
|
||
|
||
return3 ds.l 1
|
||
oldA63 ds.l 1
|
||
res ds.w 1 ; INTEGER
|
||
k ds.w 1 ; INTEGER
|
||
j ds.w 1 ; INTEGER
|
||
localFrame3 EQU *
|
||
ENDR
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
localRegs reg D7/A3/A4
|
||
ff EQU A3
|
||
ff1 EQU A4
|
||
kR EQU D7
|
||
|
||
;============================================================
|
||
WITH Str2FormFrame,MakeExpFrame,IsSubStringFrame, SMgrRecord
|
||
|
||
;determine whether the input string at this point matches whichever
|
||
;exponent string we send
|
||
|
||
LINK A6,#localFrame3
|
||
MOVEM.L localRegs,-(A7)
|
||
MOVEA.L oldA6f3(A6),ff
|
||
MOVEA.L oldA6f2(ff),ff1
|
||
MOVEQ #1,kR ;k is index into exp
|
||
MOVE.W inIndex(ff1),j(A6) ;j is index into comparator
|
||
SF returnValue3(A6) ;assume no it's not a substring
|
||
MOVEA.L exp(ff),A0 ;get the exp structure
|
||
|
||
;; compw WideCharArr.size(A0),kR ;and make sure it's not empty
|
||
;; BGT.S @out ;don't compare nothing
|
||
|
||
; <3/17/88med> since dan is using limits, not counts, a limit of zero means one character
|
||
; and since the first character has already been tested, just jump to the end to test
|
||
|
||
bra.s @LoopTest ; test for done.
|
||
|
||
@loop:
|
||
MOVEA.L inString(ff1),A0 ;if j is beyond end of inString,
|
||
CLR.W D0 ;then we're done comparing
|
||
MOVE.B (A0),D0
|
||
compw j(A6),D0
|
||
BLT.S @out
|
||
CLR.W -(A7) ;result space
|
||
PEA j(A6) ;index into inString
|
||
MOVE.L ff1,-(A7) ;the ubiquitous frame pointer
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
GetSMgrCore a0 ; setup for vector call <6/17/88ldc>
|
||
move.l sVectRetrieveChar(a0), a0 ; <6/17/88ldc>
|
||
jsr (a0)
|
||
|
||
ELSE
|
||
|
||
JSR RetrieveChar ;get the next character
|
||
|
||
ENDIF
|
||
|
||
MOVE.W (A7)+,c(ff1) ;and move it into c
|
||
MOVEA.L exp(ff),A0 ;compare c to exp.data[k]
|
||
MOVE.W kR,D0
|
||
ADD.W D0,D0
|
||
MOVE.W c(ff1),D1
|
||
compw WideCharArr.data(A0,D0.W),D1
|
||
BNE.S @out ;if it doesn't match, just leave
|
||
ADDQ.W #1,kR ;otherwise advance pointer
|
||
MOVEA.L exp(ff),A0 ;and check if we've run out of exp
|
||
|
||
;<3/18/88ldc> moved looptest up to here
|
||
@LoopTest
|
||
compw WideCharArr.size(A0),kR
|
||
BLE.S @loop
|
||
MOVE.W j(A6),inIndex(ff1) ;update index from j
|
||
ST returnValue3(A6) ;and report the results
|
||
|
||
@out:
|
||
MOVEM.L (A7)+,localRegs
|
||
UNLK A6
|
||
MOVE.L (A7)+,(A7)
|
||
RTS
|
||
|
||
CheckDebug 'ISSUBSTR'
|
||
ENDWITH
|
||
endp
|
||
|
||
;============================================================
|
||
; MakeExp
|
||
;
|
||
; trashes a0,d0,d1 (maybe a1,d2)
|
||
; uses/restores a3-a4
|
||
; calls IsSubstring, which trashes a0,d0,d1 (maybe a1,d2)
|
||
;
|
||
MakeExp proc
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
localRegs reg A3/A4
|
||
ff EQU A4
|
||
outStringR EQU A3
|
||
|
||
;============================================================
|
||
WITH Str2FormFrame,MakeExpFrame,FormatStringPriv, SMgrRecord
|
||
|
||
;if we encounter an exponent, say so and parse beyond it
|
||
;and insert the appropriate exponent character into the form string
|
||
|
||
LINK A6,#localFrame2
|
||
MOVEM.L localRegs,-(A7)
|
||
MOVEA.L oldA6f2(A6),ff
|
||
MOVEA.L outString(ff),outStringR
|
||
SF returnValue2(A6) ;assume the worst
|
||
CLR.W -(A7) ;first determine if inString is a…
|
||
MOVE.L A6,-(A7) ;…subset of exp
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
GetSMgrCore a0 ; setup for vector call <6/17/88ldc>
|
||
move.l sVectIsSubstring(a0),a0 ; <6/17/88ldc>
|
||
jsr (a0)
|
||
|
||
ELSE
|
||
|
||
JSR IsSubstring
|
||
|
||
ENDIF
|
||
|
||
MOVE.B (A7)+,D0
|
||
BEQ.S @out ;and just forget it if not
|
||
MOVE.W currentFlags(ff),D0 ;see if we've already encountered an exp
|
||
AND.L #fEMEP,D0
|
||
BEQ.S @noDupExp
|
||
MOVE.W #fExtraExp,returnValue1(ff)
|
||
BRA.S @flagOut ;set extra exponent flag and quit
|
||
@noDupExp:
|
||
BTST #fIsDecimal,currentFlags(ff)
|
||
BNE.S @contDec ;if we never ran into a decimal point…
|
||
MOVE.B formCount(ff),D0 ;then we should insert it now before the exp
|
||
EXT.W D0
|
||
ADD.W D0,D0
|
||
MOVE.W outIndex(ff),decLocs(outStringR,D0.W)
|
||
@contDec:
|
||
MOVE.W expOrd(A6),D0 ;set whichever exp flag we're dealing with
|
||
MOVE.W D0,D1
|
||
ASR.W #3,D0
|
||
BSET D1,currentFlags(ff,D0.W)
|
||
MOVE.W outIndex(ff),D0 ;append the exp symbol to the form string
|
||
MOVE.B (expChar+1)(A6),formString(outStringR,D0.W)
|
||
ADDQ.W #1,outIndex(ff) ;and increment the form string index
|
||
@flagOut:
|
||
ST returnValue2(A6) ;we did indeed encounter an exponent
|
||
@out:
|
||
MOVEM.L (A7)+,localRegs
|
||
|
||
move #argFrame2, d0 ; for StdUnlink
|
||
bra StdUnlink ; standard exit
|
||
|
||
CheckDebug 'MAKEEXP '
|
||
ENDWITH
|
||
endp
|
||
|
||
;============================================================
|
||
; ProcessLead
|
||
;
|
||
; trashes a0,d0,d1
|
||
;
|
||
ProcessLead proc
|
||
|
||
;------------------------------------------------------------
|
||
processLeadFrame record {oldA62},decrement
|
||
argFrameT2 EQU *
|
||
;x ds.w 1 ; INTEGER PASSED IN D0
|
||
oldA6f2 ds.l 1
|
||
argFrame2 EQU argFrameT2-*
|
||
|
||
return2 ds.l 1
|
||
oldA62 ds.l 1
|
||
localFrame2 EQU *
|
||
ENDR
|
||
|
||
;============================================================
|
||
WITH Str2FormFrame,processLeadFrame,FormatStringPriv
|
||
|
||
;process any digit placeholder by putting it into the form string
|
||
;and adding it to the count of digits
|
||
|
||
MOVEA.L outString(A6),A0
|
||
MOVE.W outIndex(A6),D1
|
||
MOVE.B D0,formString(A0,D1.W) ;move the leader into the form string
|
||
ADDQ.W #1,outIndex(A6) ;and advance the form string index
|
||
MOVE.W currentFlags(A6),D0 ;if we have not encountered an exponent…
|
||
AND.L #fEMEP,D0
|
||
BNE.S @out
|
||
MOVE.B formCount(A6),D0 ;then increment postDig or preDig,…
|
||
EXT.W D0 ;…depending on whether we've hit a decimal yet
|
||
ADD.W D0,D0
|
||
BTST #fIsDecimal,currentFlags(A6)
|
||
BEQ.S @noDec
|
||
ADDQ.W #1,postDig(A0,D0.W)
|
||
BRA.S @out
|
||
@noDec:
|
||
ADDQ.W #1,preDig(A0,D0.W)
|
||
@out:
|
||
RTS
|
||
|
||
CheckDebug 'PROCESSL'
|
||
ENDWITH
|
||
endp
|
||
|
||
;============================================================
|
||
; GetC
|
||
;
|
||
; trashes a0 (,d0,d1) (maybe a1,d2)
|
||
; calls RetrieveChar, which trashes a0,d0,d1 (maybe a1,d2)
|
||
;============================================================
|
||
GetC proc
|
||
WITH Str2FormFrame, SMgrRecord
|
||
|
||
;a common enough used sequence of code to justify its own routine
|
||
|
||
CLR.W -(A7) ; return space
|
||
PEA inIndex(A6) ; index into inString
|
||
MOVE.L A6,-(A7) ; frame pointer
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
GetSMgrCore a0 ; setup for vector call <6/17/88ldc>
|
||
move.l sVectRetrieveChar(a0), a0 ; <6/17/88ldc>
|
||
jsr (a0)
|
||
|
||
ELSE
|
||
|
||
JSR RetrieveChar
|
||
|
||
ENDIF
|
||
|
||
MOVE.W (A7)+,c(A6) ;and place the result in C
|
||
RTS
|
||
|
||
ENDWITH
|
||
endp
|
||
|
||
;============================================================
|
||
; xStr2Form
|
||
;
|
||
; trashes a0-a1,d0-d2
|
||
; uses/restores a3-a4,d3-d7
|
||
; calls CheckPartsIntegrity here trashes a0,d0-d2
|
||
; GetC here trashes a0,d0-d1 (maybe a1,d2)
|
||
; SendChar here trashes a0-a1,d0-d2
|
||
; ProcessLead here trashes a0,d0-d1
|
||
; CharComp here trashes a0,d0-d1
|
||
; MakeExp here trashes a0,d0-d1 (maybe a1,d2)
|
||
;
|
||
; NOTE: UprString (called by CharComp) now depends on the a5 world,
|
||
; so don't muck around with a5 before calling CharComp! <02/21/89 pke>
|
||
; Actually, UprString is again independent of a5 world, but now we're
|
||
; using LwrString instead, which DOES depend on a5 world. <06/30/89 pke>
|
||
;
|
||
xStr2Form proc
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
localRegs reg D3-D7/A3/A4 ; don't need a2,a5 <02/21/89 pke>
|
||
resR EQU D6
|
||
outStringR EQU A4
|
||
partsTableR EQU A3
|
||
altNumFlagR EQU D4
|
||
thisCodeR EQU D7
|
||
goingR EQU D5
|
||
|
||
;============================================================
|
||
WITH Str2FormFrame,FormatStringPriv,NumberParts, SMgrRecord
|
||
|
||
LINK A6,#localFrame1
|
||
MOVEM.L localRegs,-(A7)
|
||
MOVE.W #fFormatOK,returnValue1(A6) ; be optimistic about the result
|
||
MOVEQ #fFormatOK,resR ; let resR handle immediate results
|
||
CLR.W -(A7)
|
||
MOVE.L A6,-(A7)
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
GetSMgrCore a0 ; setup for vector call <6/17/88ldc>
|
||
move.l sVectCheckPartsIntegrity(a0),a0 ; <6/17/88ldc>
|
||
jsr (a0)
|
||
|
||
ELSE
|
||
|
||
JSR CheckPartsIntegrity ; first see that the parts table is ok
|
||
|
||
ENDIF
|
||
|
||
MOVE.B (A7)+,D0
|
||
BNE.S @partsTableOk ; and if it's not then report it
|
||
MOVE.W #fBadPartsTable,returnValue1(A6)
|
||
BRA @out
|
||
@partsTableOk:
|
||
MOVEA.L outString(A6),outStringR ; otherwise load up a reg or two
|
||
MOVEA.L partsTable(A6),partsTableR
|
||
MOVEQ.L #(2*fZero),D3 ; clear out all the flags
|
||
@clearFlags:
|
||
CLR.W flags(outStringR,D3.W)
|
||
CLR.W decLocs(outStringR,D3.W)
|
||
|
||
MOVE.W #1,startLocs(outStringR,D3.W) ; for null formats, point past end of string
|
||
CLR.W preDig(outStringR,D3.W)
|
||
CLR.W postDig(outStringR,D3.W)
|
||
SUBQ.B #2,D3
|
||
BPL.S @clearFlags
|
||
|
||
;; MOVE.W #fPositive,formCount(A6) ;start out with positive format string
|
||
move.b #fPositive,formCount(A6) ;start with positive format string <2/7/88med>
|
||
compw #'#',(((tokNonLeader-tokLeftQuote)*2)+data)(partsTableR)
|
||
SNE altNumFlagR ;if the nonLead symbol is not an…
|
||
BEQ.S @noAltF ;…ascii '#' then assume foreign digits
|
||
MOVE.W #fExAlF,currentFlags(A6) ;turn on the alternate digits flag…
|
||
BRA.S @altFCont ;…and the exists flag
|
||
@noAltF:
|
||
MOVE.W #fEXISTF,currentFlags(A6) ;otherwise turn on just the exists flag
|
||
@altFCont:
|
||
moveq #1,d0 ;scratch <2/7/88med>
|
||
MOVE.W d0,inIndex(A6) ;set up string indices <2/7/88med>
|
||
MOVE.W d0,outIndex(A6) ; <2/7/88med>
|
||
MOVE.B #(255-fixedLength),formString(outStringR) ;and give a maximum length
|
||
MOVEA.L inString(A6),A0
|
||
MOVE.B (A0),D0
|
||
|
||
beq @emptyInString ; detect empty instring <9/7/88ldc>
|
||
st goingR ; if inString[0] is null then don't bother
|
||
|
||
@whileGoing:
|
||
MOVE.B goingR,D0 ;still looping?
|
||
BEQ @endWhileGoing
|
||
CLR.W D0 ;if we've gone beyond the physical limits…
|
||
MOVE.B formString(outStringR),D0 ;…of the format string then bomb
|
||
compw outIndex(A6),D0
|
||
BGE.S @noOverflow
|
||
MOVE.W #fFormatOverflow,returnValue1(A6)
|
||
BRA @out
|
||
@noOverflow:
|
||
JSR GetC ;get next character in c(A6)
|
||
MOVE.W #(tokLeftQuote-1),thisCodeR ;start ourselves off at the beginning
|
||
@seekMatch:
|
||
ADDQ.W #1,thisCodeR ;pre-increment
|
||
compw #tokDecPoint,thisCodeR ;decPoint is the last we're concerned with
|
||
BGT.S @doneSeekMatch ;so if we've passed that, then forget it
|
||
MOVE.W thisCodeR,D1 ;otherwise check the char against table entries
|
||
ADD.W D1,D1
|
||
MOVE.W c(A6),D2
|
||
compw (-(tokLeftQuote*2)+data)(partsTableR,D1.W),D2
|
||
BNE.S @seekMatch ;try again if no match
|
||
@doneSeekMatch:
|
||
MOVE.W thisCodeR,D0 ;CASE thisCode OF
|
||
SUBQ.W #tokLeftQuote,D0 ;leftQuote is lowest
|
||
BMI @endCase
|
||
compw #(tokEPlus-tokLeftQuote),D0 ;EPlus is the highest
|
||
BGT @endCase
|
||
ADD.W D0,D0
|
||
MOVE.W @jTab(D0.W),D0
|
||
JMP *+2(D0.W)
|
||
@jTab:
|
||
DC.W @leftQuote-@jTab+2, @rightQuote-@jTab+2, @leadPlacer-@jTab+2
|
||
DC.W @garbage-@jTab+2, @rLeads-@jTab+2, @rLeads-@jTab+2
|
||
DC.W @percent-@jTab+2, @signs-@jTab+2, @signs-@jTab+2
|
||
DC.W @signs-@jTab+2, @garbage-@jTab+2, @separator-@jTab+2
|
||
DC.W @garbage-@jTab+2, @decPoint-@jTab+2, @others-@jTab+2
|
||
|
||
@leftQuote:
|
||
@seekRightQuote:
|
||
JSR GetC ;just start looking for right qoute
|
||
MOVE.W c(A6),D0 ;but beware of escapes
|
||
compw (((tokEscape-tokLeftQuote)*2)+data)(partsTableR),D0
|
||
BNE.S @escapeMerge
|
||
JSR GetC ;found escape so just go right into next char
|
||
CLR.W -(A7)
|
||
MOVE.W c(A6),-(A7)
|
||
PEA formString(outStringR)
|
||
PEA outIndex(A6) ;and process it
|
||
JSR SendChar
|
||
OR.W (A7)+,resR
|
||
;<1/29/88drs> Changed 1 line to fix bug
|
||
;Could have two escape+c in a row, so loop back to seekRightQuote
|
||
BRA.S @seekRightQuote
|
||
@escapeMerge:
|
||
MOVE.W c(A6),D0 ;check for right quote
|
||
BEQ.S @L902
|
||
compw (((tokRightQuote-tokLeftQuote)*2)+data)(partsTableR),D0
|
||
BEQ @endCase ;and just quit if we find it
|
||
CLR.W -(A7) ;otherwise send out whatever we find
|
||
MOVE.W c(A6),-(A7)
|
||
PEA formString(outStringR)
|
||
PEA outIndex(A6)
|
||
JSR SendChar
|
||
OR.W (A7)+,resR
|
||
BRA.S @seekRightQuote
|
||
@L902:
|
||
MOVE.W #fMissingLiteral,returnValue1(A6)
|
||
BRA @endCase
|
||
|
||
@rightQuote: ;right quote without left is an error
|
||
MOVE.W #fMissingDelimiter,returnValue1(A6)
|
||
BRA @endCase
|
||
|
||
@rLeads: ;either zeroLead or nonLead comes here
|
||
MOVE.W thisCodeR,D0
|
||
JSR ProcessLead
|
||
BRA @endCase
|
||
|
||
@leadPlacer: ;lead placer is replaced by the actual lead symbol
|
||
MOVE.W #tokLeader,D0
|
||
JSR ProcessLead
|
||
BRA @endCase
|
||
|
||
@decPoint:
|
||
BTST #fIsDecimal,currentFlags(A6)
|
||
BEQ.S @noExtraDec ;error if more than one decimal
|
||
MOVE.W #fExtraDecimal,returnValue1(A6)
|
||
BRA.S @dOut
|
||
@noExtraDec:
|
||
MOVE.W outIndex(A6),D0 ;append decimal point to format string
|
||
MOVE.B #tokDecPoint,formString(outStringR,D0.W)
|
||
MOVE.B formCount(A6),D0 ;and record its position
|
||
EXT.W D0
|
||
ADD.W D0,D0
|
||
MOVE.W outIndex(A6),decLocs(outStringR,D0.W)
|
||
ADDQ.W #1,outIndex(A6) ;increment form string index
|
||
BSET #fIsDecimal,currentFlags(A6) ;and say we got a decimal point
|
||
@dOut:
|
||
BRA @endCase
|
||
|
||
@percent:
|
||
BTST #fIsPercent,currentFlags(A6) ;make sure we don't already…
|
||
BEQ.S @noExtraPercent ;…have a percent sign
|
||
MOVE.W #fExtraPercent,returnValue1(A6) ;record error if we do
|
||
BRA.S @pOut
|
||
@noExtraPercent:
|
||
BSET #fIsPercent,currentFlags(A6) ;say we got one
|
||
MOVE.W outIndex(A6),D0 ;and record its position
|
||
MOVE.B thisCodeR,formString(outStringR,D0.W)
|
||
ADDQ.W #1,outIndex(A6) ;increment form string pointer
|
||
|
||
@pOut:
|
||
BRA @endCase
|
||
|
||
@separator:
|
||
compb #fZero,formCount(A6) ;if we've already got 3 formats…
|
||
BNE.S @noExtraSep ;…then it's an error
|
||
MOVE.W #fExtraSeparator,returnValue1(A6)
|
||
BRA.S @sOut
|
||
@noExtraSep:
|
||
MOVE.B formCount(A6),D1 ;if we have no decimal point,…
|
||
EXT.W D1 ;…and no exponent then make up a…
|
||
ADD.W D1,D1 ;…decimal point
|
||
MOVE.W currentFlags(A6),D0
|
||
AND.L #fDEMEP,D0
|
||
BNE.S @noFakeDec
|
||
MOVE.W outIndex(A6),decLocs(outStringR,D1.W)
|
||
@noFakeDec:
|
||
|
||
MOVE.W preDig(outStringR,D1.W),D0 ;
|
||
ADD.W postDig(outStringR,D1.W),D0 ;
|
||
BNE.S @nullFmtTest1Done ;if preDig+postDig≠0, OK
|
||
MOVE.W outIndex(A6),D0 ;
|
||
CMP.W startLocs(outStringR,D1.W),D0 ;
|
||
BLE.S @nullFmtTest1Bad ;otherwise, bad if null length
|
||
MOVE.W currentFlags(A6),D0 ;
|
||
AND.W #fDPEMEP,D0 ;otherwise, if no dec pt, percent,
|
||
BEQ.S @nullFmtTest1Done ; or exponent, then OK
|
||
@nullFmtTest1Bad: ;
|
||
CLR.W flags(outStringR,D1.W) ;
|
||
MOVE.W #fEmptyFormatString,resR ;
|
||
BRA @nullFmtExit ;
|
||
@nullFmtTest1Done:
|
||
|
||
MOVE.W currentFlags(A6),flags(outStringR,D1.W) ;save flag set
|
||
ADDQ.B #1,formCount(A6) ;advance formCount
|
||
MOVE.B altNumFlagR,D0 ;record just-finished format's…
|
||
BEQ.S @noAltDig ;…alternate digit record
|
||
MOVE.W #fExAlF,currentFlags(A6)
|
||
BRA.S @mergeAltDig
|
||
@noAltDig:
|
||
MOVE.W #fEXISTF,currentFlags(A6)
|
||
@mergeAltDig:
|
||
MOVE.B formCount(A6),D0 ;and record the starting location…
|
||
EXT.W D0 ;…of this format
|
||
ADD.W D0,D0
|
||
MOVE.W outIndex(A6),startLocs(outStringR,D0.W)
|
||
@sOut:
|
||
BRA @endCase
|
||
|
||
@signs: ;plus, minus, thousands
|
||
MOVE.W outIndex(A6),D0 ;just record its position
|
||
MOVE.B thisCodeR,formString(outStringR,D0.W)
|
||
ADDQ.W #1,outIndex(A6) ;and increment form string index
|
||
BRA @endCase
|
||
|
||
@garbage: ;escape, noRoomFill, leader
|
||
MOVE.W #fSpuriousChars,returnValue1(A6)
|
||
BRA @endCase
|
||
|
||
@others: ;including exponents and unquoteds
|
||
; MOVE.W c(A6),D0 ;Check against E+ format
|
||
; compw (PePlus+WideCharArr.data)(partsTableR),D0
|
||
;<3/15/88ldc> added case insensitive character comparison routine "CharComp"
|
||
clr.w -(a7)
|
||
move.w c(a6), -(a7)
|
||
move.w (PePlus+WideCharArr.data)(partsTableR), -(a7)
|
||
jsr CharComp
|
||
tst.b (a7)+
|
||
beq.s @notEPlus ;if partsTable.PePlus.data <> c then not EPlus
|
||
CLR.W -(A7) ;result room
|
||
PEA PePlus(partsTableR)
|
||
MOVE.W #fIsEPlus,-(A7)
|
||
MOVE.W #tokEPlus,-(A7)
|
||
MOVE.L A6,-(A7)
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
GetSMgrCore a0 ; setup for vector call <6/17/88ldc>
|
||
move.l sVectMakeExp(a0), a0 ; <6/17/88ldc>
|
||
jsr (a0)
|
||
|
||
ELSE
|
||
|
||
JSR MakeExp ;see if the entire EPlus is there
|
||
|
||
ENDIF
|
||
|
||
MOVE.B (A7)+,D0
|
||
BNE.S @matchEPlus
|
||
CLR.W -(A7) ;if not then try EMinus
|
||
PEA PeMinus(partsTableR)
|
||
MOVE.W #fIsEMinus,-(A7)
|
||
MOVE.W #tokEMinus,-(A7)
|
||
MOVE.L A6,-(A7)
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
GetSMgrCore a0 ; setup for vector call <6/17/88ldc>
|
||
move.l sVectMakeExp(a0), a0 ; <6/17/88ldc>
|
||
jsr (a0)
|
||
|
||
ELSE
|
||
|
||
JSR MakeExp ;see if the entire EPlus is there
|
||
|
||
ENDIF
|
||
|
||
MOVE.B (A7)+,D0
|
||
BNE.S @matchEMinus
|
||
MOVE.W #fSpuriousChars,returnValue1(A6) ;otherwise it's junk
|
||
@matchEPlus:
|
||
@matchEMinus:
|
||
BRA.S @endCase
|
||
@notEPlus:
|
||
; MOVE.W c(A6),D0
|
||
; compw (PeMinus+WideCharArr.data)(partsTableR),D0
|
||
;<3/15/88ldc> added case insensitive character comparison routine "CharComp"
|
||
clr.w -(a7) ;try EMinus
|
||
move.w c(a6), -(a7)
|
||
move.w (PeMinus+WideCharArr.data)(partsTableR), -(a7)
|
||
jsr CharComp
|
||
tst.b (a7)+
|
||
beq.S @notEMinus
|
||
CLR.W -(A7)
|
||
PEA PeMinus(partsTableR)
|
||
MOVE.W #fIsEMinus,-(A7)
|
||
MOVEQ #tokEMinus,D0
|
||
MOVE.W D0,-(A7)
|
||
MOVE.L A6,-(A7)
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
GetSMgrCore a0 ; setup for vector call <6/17/88ldc>
|
||
move.l sVectMakeExp(a0), a0 ; <6/17/88ldc>
|
||
jsr (a0)
|
||
|
||
ELSE
|
||
|
||
JSR MakeExp ;see if the entire EPlus is there
|
||
|
||
ENDIF
|
||
|
||
MOVE.B (A7)+,D0
|
||
BNE.S @wasEMinus ;if this didn't work then it's junk
|
||
MOVE.W #fSpuriousChars,returnValue1(A6)
|
||
@wasEMinus:
|
||
BRA.S @endCase
|
||
@notEMinus:
|
||
LEA ((tokMaxSymbols-1)*2)(partsTableR),A1
|
||
MOVE.W c(A6),D1 ;try the unquoteds table
|
||
BEQ.S @junkC ;a null char is unfathomable
|
||
MOVEQ #(tokEMinus-1),D2 ;loop counter
|
||
@UQLoop:
|
||
compw -(A1),D1
|
||
DBEQ D2,@UQLoop ;stop if a match
|
||
BNE.S @junkC ;this character doesn't belong
|
||
CLR.W -(A7) ;send the code off
|
||
MOVE.W c(A6),-(A7)
|
||
PEA formString(outStringR)
|
||
PEA outIndex(A6)
|
||
JSR SendChar
|
||
OR.W (A7)+,resR
|
||
BRA.S @endCase
|
||
@junkC:
|
||
MOVE.W #fSpuriousChars,returnValue1(A6)
|
||
|
||
@endCase:
|
||
MOVEA.L inString(A6),A0 ;make sure we haven't exceeded the input string
|
||
CLR.W D0
|
||
MOVE.B (A0),D0
|
||
compw inIndex(A6),D0
|
||
BGE.S @cGo
|
||
SF goingR
|
||
@cGo:
|
||
BRA @whileGoing
|
||
|
||
@emptyInString
|
||
move.w #fEmptyFormatString, resR ;signal empty format string <9/7/88ldc>
|
||
bclr.b #fExists,currentFlags(A6) ;turn off exists flag <05/22/89 pke>
|
||
|
||
@endWhileGoing:
|
||
MOVE.B formCount(A6),D1 ;update flags from temp flag word
|
||
EXT.W D1
|
||
ADD.W D1,D1
|
||
|
||
MOVE.W preDig(outStringR,D1.W),D0 ;
|
||
ADD.W postDig(outStringR,D1.W),D0 ;
|
||
BNE.S @nullFmtTest2Done ;if preDig+postDig≠0, OK
|
||
MOVE.W outIndex(A6),D0 ;
|
||
CMP.W startLocs(outStringR,D1.W),D0 ;
|
||
BLE.S @nullFmtTest2Bad ;otherwise, bad if null length
|
||
MOVE.W currentFlags(A6),D0 ;
|
||
AND.W #fDPEMEP,D0 ;otherwise, if no dec pt, percent,
|
||
BEQ.S @nullFmtTest2Done ; or exponent, then OK
|
||
@nullFmtTest2Bad: ;
|
||
CLR.W currentFlags(A6) ;
|
||
MOVE.W #fEmptyFormatString,resR ;
|
||
@nullFmtTest2Done:
|
||
|
||
MOVE.W currentFlags(A6),flags(outStringR,D1.W)
|
||
|
||
MOVEQ #0,D0 ;if we never hit decimal or exponent…
|
||
MOVE.W currentFlags(A6),D0 ;…then make up a decimal point at…
|
||
AND.L #fDEMEP,D0 ;…this position
|
||
BNE.S @contDEMEP
|
||
|
||
MOVE.W outIndex(A6),decLocs(outStringR,D1.W)
|
||
|
||
@contDEMEP:
|
||
@nullFmtExit: ; <05/22/89 pke>
|
||
CMP.B #fPositive,formCount(A6)
|
||
BNE.S @notPos ;if the last form was positive then init others
|
||
MOVE.W outIndex(A6),(startLocs+(2*fNegative))(outStringR)
|
||
@doZero:
|
||
MOVE.W outIndex(A6),(startLocs+(2*fZero))(outStringR)
|
||
BRA.S @mergeP
|
||
@notPos:
|
||
compb #fNegative,formCount(A6)
|
||
BEQ.S @doZero
|
||
|
||
@mergeP:
|
||
MOVE.W outIndex(A6),startLocs(outStringR)
|
||
MOVE.W outIndex(A6),D0 ;set startLocs[fPositive] past last form string code
|
||
SUBQ.W #1,D0
|
||
MOVE.B D0,formString(outStringR)
|
||
;<1/23/88drs> Added 2 lines to compute dynamic record length
|
||
ADD.B #fixedLength,D0
|
||
MOVE.B D0,fLength(outStringR)
|
||
|
||
compw #fFormatOK,resR ;if resR got changed then say so
|
||
BEQ.S @out
|
||
MOVE.W resR,returnValue1(A6)
|
||
@out:
|
||
;<1/23/88drs> Added 1 line to insert version number
|
||
MOVE.B #fVNumber,fVersion(outStringR)
|
||
MOVEM.L (A7)+,localRegs
|
||
|
||
move #argFrame1, d0 ; for StdUnlink
|
||
bra StdUnlink ; standard exit
|
||
|
||
CheckDebug 'STR2FORM'
|
||
endp
|
||
|
||
|
||
maxString EQU 50
|
||
|
||
;------------------------------------------------------------
|
||
Form2StrFrame record {oldA61},decrement
|
||
returnValue1 ds.w 1 ; INTEGER
|
||
argFrameT1 EQU *
|
||
myCanonical ds.l 1 ; VAR NumFormatString
|
||
partsTable ds.l 1 ; VAR NumberParts
|
||
outString ds.l 1 ; VAR str255
|
||
positions ds.l 1 ; VAR TripleInt
|
||
selector1 ds.l 1
|
||
argFrame1 EQU argFrameT1-*
|
||
|
||
return1 ds.l 1
|
||
oldA61 ds.l 1
|
||
|
||
res ds.w 1 ; INTEGER
|
||
;<4/1/88ldc> removed the unused i
|
||
;i ds.w 1 ; INTEGER
|
||
j ds.w 1 ; INTEGER
|
||
formCount ds.b 1 ; formatClass
|
||
hold12 ds.l 1
|
||
hold11 ds.w 1
|
||
inLiteral ds.b 1 ; boolean
|
||
pad ds.b 1
|
||
localFrame1 EQU *
|
||
ENDR
|
||
|
||
;------------------------------------------------------------
|
||
TranslateToTextFrame record {oldA62},decrement
|
||
argFrameT2 EQU *
|
||
source ds.w 1 ; CHAR
|
||
oldA6f2 ds.l 1
|
||
argFrame2 EQU argFrameT2-*
|
||
|
||
return2 ds.l 1
|
||
oldA62 ds.l 1
|
||
addendum ds.b maxString ; string
|
||
iIndex ds.w 1 ; INTEGER
|
||
hold2 ds.w 1
|
||
localFrame2 EQU *
|
||
ENDR
|
||
|
||
;============================================================
|
||
; TackOnExp
|
||
;
|
||
; trashes a0,d0
|
||
; uses/restores a2-a4,d7
|
||
; calls SendChar, which trashes a0-a1,d0-d2
|
||
;
|
||
TackOnExp proc
|
||
|
||
;------------------------------------------------------------
|
||
TackOnExpFrame record {oldA63},decrement
|
||
argFrameT3 EQU *
|
||
exp ds.l 1 ; VAR WideCharArr
|
||
oldA6f3 ds.l 1
|
||
argFrame3 EQU argFrameT3-*
|
||
|
||
return3 ds.l 1
|
||
oldA63 ds.l 1
|
||
xj ds.w 1
|
||
hold3 ds.w 1
|
||
localFrame3 EQU *
|
||
ENDR
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
localRegs reg D7/A2-A4 ; don't need a5 <02/21/89 pke>
|
||
|
||
ff EQU A3
|
||
ff1 EQU A4
|
||
expR EQU A2
|
||
|
||
;============================================================
|
||
WITH Form2StrFrame,TranslateToTextFrame,TackOnExpFrame
|
||
|
||
;FOR xj:= 0 TO exp.size DO BEGIN
|
||
; res:= SendChar(exp.data[xj], addendum, i); END;
|
||
|
||
LINK A6,#localFrame3
|
||
MOVEM.L localRegs,-(A7)
|
||
MOVEA.L oldA6f3(A6),ff
|
||
MOVEA.L oldA6f2(ff),ff1
|
||
MOVEA.L exp(A6),expR
|
||
MOVE.W WideCharArr.size(expR),hold3(A6)
|
||
LEA WideCharArr.data(expR),expR
|
||
CLR.W D7
|
||
BRA.S @L448
|
||
@L451:
|
||
CLR.W -(A7)
|
||
MOVE.W (expR)+,-(A7)
|
||
PEA addendum(ff)
|
||
PEA iIndex(ff)
|
||
JSR SendChar
|
||
MOVE.W (A7)+,res(ff1)
|
||
ADDQ.W #1,D7
|
||
@L448:
|
||
compw hold3(A6),D7
|
||
BLE.S @L451
|
||
@L450:
|
||
MOVEM.L (A7)+,localRegs
|
||
|
||
move #argFrame3, d0 ; for StdUnlink
|
||
bra StdUnlink ; standard exit
|
||
|
||
CheckDebug 'TACKONEX'
|
||
ENDWITH
|
||
endp
|
||
|
||
;============================================================
|
||
TranslateToText proc
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
localRegs reg D7/A3/A4
|
||
sourceR EQU D7
|
||
ff EQU A4
|
||
partsTableR EQU A3
|
||
|
||
;============================================================
|
||
WITH Form2StrFrame,TranslateToTextFrame,NumberParts, SMgrRecord
|
||
|
||
LINK A6,#localFrame2
|
||
MOVEM.L localRegs,-(A7)
|
||
MOVE.W source(A6),sourceR
|
||
MOVEA.L oldA6f2(A6),ff
|
||
|
||
;WITH partsTable DO BEGIN
|
||
; i:= 1;
|
||
; addendum[0]:= CHR(maxString-1);
|
||
|
||
MOVEA.L partsTable(ff),partsTableR
|
||
MOVE.W #1,iIndex(A6)
|
||
MOVE.B #(maxString-1),addendum(A6)
|
||
|
||
;IF ORD(source) < maxSymbols+1 THEN BEGIN
|
||
; CASE ORD(source) OF
|
||
|
||
TransSendMask set 1<<tokLeader++1<<tokZeroLead
|
||
TransSendMask set TransSendMask++1<<tokNonLeader++1<<tokDecPoint++1<<tokPercent
|
||
TransSendMask set TransSendMask++1<<tokPlusSign++1<<tokMinusSign++1<<tokThousands
|
||
; remove 1<<tokLeftQuote++1<<rightQuote++1<<escape-- they should not occur
|
||
|
||
compw #(tokMaxSymbols+1),sourceR
|
||
BGE @TransLiteral ; changed branch from short <3/14/88ldc>
|
||
|
||
; if not now in literal, send a left quote if was inliteral <2/7/88med>
|
||
|
||
tst.b inLiteral(ff) ; inside quoted literal?
|
||
beq.s @NoLiteral ; no, done
|
||
sf inLiteral(ff) ; out of here
|
||
CLR.W -(A7)
|
||
MOVE.W ((tokLeftQuote-tokLeftQuote)*2+data)(partsTableR),-(A7)
|
||
PEA addendum(A6)
|
||
PEA iIndex(A6)
|
||
JSR SendChar
|
||
MOVE.W (A7)+,res(ff)
|
||
@NoLiteral
|
||
|
||
;; MOVE.L #$000067F6,D0
|
||
move.l #TransSendMask,d0 ; use equate
|
||
BTST.L sourceR,D0
|
||
BNE.S @SendTransChar
|
||
;; MOVE.L #$00001808,D0 ; indicate anything unknown
|
||
;; BTST.L sourceR,D0 ;
|
||
;; BNE.S @TransUnknownChar ; now at end of tests
|
||
compw #tokEPlus,sourceR
|
||
BEQ.S @TransExpPlus
|
||
compw #tokEMinus,sourceR
|
||
BEQ.S @TransExpMinus
|
||
BRA.S @TransUnknownChar ; anything we don't know
|
||
|
||
; leftQuote,
|
||
; rightQuote,
|
||
; leader,
|
||
; zeroLead,
|
||
; nonLeader,
|
||
; decPoint,
|
||
; percent,
|
||
; plusSign,
|
||
; minusSign,
|
||
; thousands,
|
||
; escape: res:= SendChar(data[ORD(source)], addendum, i);;
|
||
|
||
@SendTransChar:
|
||
CLR.W -(A7)
|
||
|
||
; fix leader
|
||
move.w #tokLeadPlacer*2,d0 ; assume special case <2/8/88med>
|
||
cmp.w #tokLeader,sourceR ; special case <2/8/88med>
|
||
beq.s @GotFixedChar ; <2/8/88med>
|
||
MOVE.W sourceR,D0
|
||
ADD.W D0,D0
|
||
@GotFixedChar
|
||
MOVE.W (-(tokLeftQuote*2)+data)(partsTableR,D0.W),-(A7)
|
||
PEA addendum(A6)
|
||
PEA iIndex(A6)
|
||
JSR SendChar
|
||
MOVE.W (A7)+,res(ff)
|
||
BRA.S @TransDone
|
||
|
||
; noRoomFill,
|
||
; leadPlacer,
|
||
; separator: BEGIN
|
||
; addendum:= '???';
|
||
; i:= 4; END;
|
||
|
||
@TransUnknownChar:
|
||
MOVE.L #('???' + (3 << 24)),addendum(A6)
|
||
|
||
MOVE.W #4,iIndex(A6)
|
||
BRA.S @TransDone
|
||
|
||
; ePlus: TackOnExp( PePlus );
|
||
|
||
@TransExpPlus:
|
||
PEA PePlus(partsTableR)
|
||
bra.s @TransExpCommon ; join common code <2/7/88med>
|
||
;; MOVE.L A6,-(A7) ; common <2/7/88med>
|
||
;; JSR TackOnExp ; common <2/7/88med>
|
||
;; BRA.S @TransDone ; common <2/7/88med>
|
||
|
||
; eMinus: TackOnExp( PeMinus ); END;
|
||
|
||
@TransExpMinus:
|
||
PEA PeMinus(partsTableR)
|
||
@TransExpCommon
|
||
MOVE.L A6,-(A7) ; common <2/7/88med>
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
GetSMgrCore a0 ; setup and call vector <6/17/88ldc>
|
||
move.l sVectTackOnExp(a0), a0 ; <6/17/88ldc>
|
||
jsr (a0)
|
||
|
||
ELSE
|
||
|
||
JSR TackOnExp ; common <2/7/88med>
|
||
|
||
ENDIF
|
||
|
||
bra.s @TransDone ; done tran char.
|
||
|
||
@TransLiteral:
|
||
; new tests <2/7/88med>
|
||
tst.b inLiteral(ff) ; in literal? <2/7/88med>
|
||
bne.s @AlreadyIn ; no, go
|
||
CLR.W -(A7)
|
||
; changed -data to +data <3/14/88ldc>
|
||
MOVE.W ((tokLeftQuote-tokLeftQuote)*2+data)(partsTableR),-(A7)
|
||
PEA addendum(A6)
|
||
PEA iIndex(A6)
|
||
JSR SendChar
|
||
MOVE.W (A7)+,res(ff)
|
||
st inLiteral(ff) ; in literal? <2/7/88med>
|
||
@AlreadyIn
|
||
|
||
; are we in an escape or do we have an escaped rightQuote?
|
||
; changed -data to +data <3/14/88ldc>
|
||
|
||
move.w ((tokEscape-tokLeftQuote)*2+data)(partsTableR),d0 ; get tokEscape
|
||
cmp.w d0,sourceR ; got tokEscape?
|
||
beq.s @EscapeIt
|
||
cmp.w ((tokRightQuote-tokLeftQuote)*2+data)(partsTableR),sourceR ; got tokRightQuote?
|
||
bne.s @EscapeOk
|
||
@EscapeIt
|
||
CLR.W -(A7)
|
||
MOVE.W d0,-(A7) ; pass escape char.
|
||
PEA addendum(A6)
|
||
PEA iIndex(A6)
|
||
JSR SendChar
|
||
MOVE.W (A7)+,res(ff)
|
||
@EscapeOk
|
||
|
||
CLR.W -(A7)
|
||
MOVE.W sourceR,-(A7)
|
||
PEA addendum(A6)
|
||
PEA iIndex(A6)
|
||
JSR SendChar
|
||
MOVE.W (A7)+,res(ff)
|
||
;; MOVE.W #(' ' + (1 << 8)),addendum(A6) ; forget <2/7/88med>
|
||
;; MOVE.B sourceR,addendum(A6,d0) ; add byte
|
||
; reorder TransDone to drop thru <2/7/88med>
|
||
|
||
@TransDone:
|
||
; addendum[0]:= CHR(i-1); END
|
||
; ELSE BEGIN
|
||
; addendum:= ' ';
|
||
; addendum[1]:= source;
|
||
; END;
|
||
|
||
MOVE.W iIndex(A6),D0
|
||
SUBQ.W #1,D0
|
||
MOVE.B D0,addendum(A6)
|
||
|
||
@TransFinished:
|
||
CLR.W D0
|
||
MOVE.B addendum(A6),D0
|
||
MOVE.W D0,hold2(A6)
|
||
|
||
; FOR i:= 1 TO ORD(addendum[0]) DO BEGIN
|
||
; s[j]:= addendum[i];
|
||
; j:= j + 1; END; END;
|
||
|
||
MOVE.W #1,iIndex(A6)
|
||
BRA.S @CopyLoopTest
|
||
@CopyLoop:
|
||
MOVEA.L outString(ff),A0
|
||
MOVE.W j(ff),D0
|
||
MOVE.W iIndex(A6),D1
|
||
CLR.W D2
|
||
LEA addendum(A6),A1
|
||
MOVE.B 0(A1,D1.W),0(A0,D0.W)
|
||
ADDQ.W #1,j(ff)
|
||
ADDQ.W #1,iIndex(A6)
|
||
@CopyLoopTest:
|
||
MOVE.W iIndex(A6),D0
|
||
compw hold2(A6),D0
|
||
BLE.S @CopyLoop
|
||
|
||
MOVEM.L (A7)+,localRegs
|
||
|
||
move #argFrame2, d0 ; for StdUnlink
|
||
bra StdUnlink ; standard exit
|
||
|
||
CheckDebug 'TRANSLAT'
|
||
ENDWITH
|
||
endp
|
||
|
||
;============================================================
|
||
;
|
||
;
|
||
; calls _CharByte
|
||
;
|
||
CheckForm proc
|
||
|
||
;------------------------------------------------------------
|
||
CheckFormFrame record {oldA62},decrement
|
||
argFrameT2 EQU *
|
||
x ds.w 1 ; formatClass
|
||
oldA6f2 ds.l 1
|
||
argFrame2 EQU argFrameT2-*
|
||
|
||
return2 ds.l 1
|
||
oldA62 ds.l 1
|
||
;i ds.w 1 ; INTEGER - unused, removed <4/1/88ldc>
|
||
hold22 ds.l 1
|
||
hold21 ds.w 1
|
||
localFrame2 EQU *
|
||
ENDR
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
localRegs reg D3-D7/A2-A4
|
||
ff EQU A4
|
||
myCanonicalR EQU A3
|
||
|
||
xRw EQU D3
|
||
rChar equ d5 ; added <2/7/88med>
|
||
iR EQU D6
|
||
xR EQU D7
|
||
|
||
;============================================================
|
||
WITH Form2StrFrame,CheckFormFrame,NumberParts,FormatStringPriv
|
||
|
||
LINK A6,#localFrame2
|
||
MOVEM.L localRegs,-(A7)
|
||
MOVE.B x(A6),xR
|
||
MOVEA.L oldA6f2(A6),ff
|
||
MOVEA.L myCanonical(ff),myCanonicalR
|
||
MOVEA.L partsTable(ff),A0
|
||
MOVE.L A0,hold22(A6)
|
||
|
||
;<4/4/88ldc> initialize rChar to eliminate garbage at boot time
|
||
CLR.W rChar
|
||
|
||
MOVE.B xR,xRw
|
||
EXT.W xRw
|
||
ADD.W xRw,xRw
|
||
|
||
;WITH myCanonical, partsTable DO BEGIN
|
||
; IF startLocs[x] <= startLocs[ NextFormatClass(x)]-1 THEN BEGIN
|
||
|
||
MOVE.B xR,D0
|
||
JSR NextFormatClass
|
||
ADD.W D0,D0
|
||
|
||
MOVE.W startLocs(myCanonicalR,D0.W),D2
|
||
|
||
SUBQ.W #1,D2
|
||
MOVE.W D2,hold21(A6) ; moved from below <2/7/88med>
|
||
|
||
; special test for first case, since we wrap
|
||
move.l #1,iR ; assume first (1) <2/7/88med>
|
||
compw #fPositive,xR ; first one? <2/7/88med>
|
||
beq.s @SkipFirst ; yes, bail <2/7/88med>
|
||
|
||
move.w startLocs(myCanonicalR,xRw.W),iR ; broke up comp, made common <2/7/88med>
|
||
|
||
compw iR,d2 ; was d0 <2/7/88med>
|
||
BLT.s @checkOut
|
||
|
||
; res:= SendChar(data[separator], s, j);
|
||
; positions[x].start:= j;
|
||
;<3/18/88ldc> added NumberParts.data offset
|
||
move.w #((tokSeparator-tokLeftQuote)*2+NumberParts.data),d0 ; item to send <2/7/88med>
|
||
bsr.s SendItem ; do it <2/7/88med>
|
||
|
||
MOVE.L positions(ff),A0
|
||
MOVE.B xR,D0
|
||
EXT.W D0
|
||
ASL.W #2,D0
|
||
MOVE.W j(ff),FVector.start(A0,D0.W)
|
||
|
||
@SkipFirst
|
||
|
||
; FOR i:= startLocs[x] TO startLocs[NextFormatClass(x)]-1 DO BEGIN
|
||
; TranslateToText( formString[i] ); END;
|
||
|
||
;; MOVE.B xR,xRw ; axe all common code <2/7/88med>
|
||
;; EXT.W xRw
|
||
;; ADD.W xRw,xRw
|
||
;; MOVE.B xR,D0
|
||
;; JSR NextFormatClass
|
||
;; ADD.W D0,D0
|
||
;; MOVE.W (startLocs+(fPositive*2))(myCanonicalR,D0.W),D2
|
||
;; SUBQ.W #1,D2
|
||
;; MOVE.W D2,hold21(A6)
|
||
;; MOVE.W (startLocs+(fPositive*2))(myCanonicalR,xRw.W),iR
|
||
|
||
BRA.S @loopTest
|
||
@checkLoop:
|
||
|
||
;; MOVE.W iR,D0
|
||
CLR.W D1
|
||
lea formString(myCanonicalR,iR.W),a0 ; position for char, ir.w was d0.w <2/7/88med>
|
||
MOVE.B (a0)+,rChar ; get first byte
|
||
|
||
; pass a character, not a byte; so we can do escape properly
|
||
|
||
clr.w -(sp) ; reserve return
|
||
move.l a0,-(sp) ; pass ptr
|
||
move.w #0,-(sp) ; pass offset
|
||
_CharByte
|
||
tst.w (sp)+ ; 0 for single
|
||
beq.s @GotChar
|
||
asl.w #8,rChar ; moven on up
|
||
move.b (a0),rChar ; next byte
|
||
ADDQ.W #1,iR ; bump counter
|
||
@GotChar
|
||
|
||
MOVE.W rChar,-(A7)
|
||
MOVE.L oldA6f2(A6),-(A7) ;spurious: ff has this value
|
||
JSR TranslateToText
|
||
ADDQ.W #1,iR
|
||
;; BVS.S @L472 ; don't think we will overflow <2/7/88med>
|
||
|
||
@loopTest:
|
||
compw hold21(A6),iR
|
||
BLE.S @checkLoop
|
||
|
||
; positions[x].length:= j-positions[x].start; END; END;
|
||
|
||
;;@L472: ; this label is not used <6/28/88ldc>
|
||
; moved the following chunk down & fixed below <05/22/89 pke>
|
||
|
||
; send a right quote if not done <2/7/88med>
|
||
|
||
tst.b inLiteral(ff) ; inside quoted literal?
|
||
beq.s @NoLiteral ; no, done
|
||
sf inLiteral(ff) ; out of here
|
||
; added NumberParts.data <3/18/88ldc>
|
||
move.w #((tokRightQuote-tokLeftQuote)*2+NumberParts.data),d0 ; item to send <2/7/88med>
|
||
bsr.s SendItem ; do it <2/7/88med>
|
||
@NoLiteral
|
||
|
||
; move the following 7 lines here from above <05/22/89 pke>
|
||
MOVE.L positions(ff),A0
|
||
MOVE.B xR,D0
|
||
EXT.W D0
|
||
ASL.W #2,D0
|
||
MOVE.W j(ff),D1
|
||
SUB.W FVector.start(A0,D0.W),D1
|
||
MOVE.W D1,FVector.length(A0,D0.W)
|
||
|
||
@checkOut:
|
||
MOVEM.L (A7)+,localRegs
|
||
move #argFrame2, d0 ; for StdUnlink
|
||
bra StdUnlink ; standard exit
|
||
|
||
CheckDebug 'CHECKFOR'
|
||
|
||
;============================================================
|
||
; simple subproc for above
|
||
SendItem
|
||
CLR.W -(A7)
|
||
MOVEA.L hold22(A6),A0
|
||
MOVE.W 0(a0,d0.w),-(A7) ; generalized <2/7/88med>
|
||
MOVE.L outString(ff),-(A7)
|
||
PEA j(ff)
|
||
JSR SendChar
|
||
MOVE.W (A7)+,res(ff)
|
||
|
||
|
||
rts
|
||
endProc
|
||
|
||
;============================================================
|
||
xForm2Str proc
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
|
||
localRegs reg D6/D7/A3-A4
|
||
procVectR equ a3 ; for vectored proc <6/21/88ldc>
|
||
|
||
myCanonicalR EQU A4
|
||
iR EQU D6
|
||
|
||
;============================================================
|
||
WITH Form2StrFrame,FormatStringPriv,NumberParts, SMgrRecord
|
||
|
||
LINK A6,#localFrame1
|
||
MOVEM.L localRegs,-(A7)
|
||
|
||
;Format2Str:= ORD(formatOk);
|
||
;res:= ORD(formatOk);
|
||
;xxx <2/23/88:ldc> replaced #1 with symbolic constant fFormatOK
|
||
|
||
MOVE.W #fFormatOK,returnValue1(A6)
|
||
MOVE.W #fFormatOK,res(A6)
|
||
|
||
; must initialize outString to Str255 <3/28/88ldc>
|
||
MOVEA.L outString(A6),A0
|
||
MOVE.B #$FF,(A0)
|
||
|
||
;FOR formCount:= positive TO zero DO BEGIN
|
||
; positions[formCount].start:= 0;
|
||
; positions[formCount].length:= 0; END;
|
||
|
||
MOVE.L positions(A6),A0
|
||
MOVEQ #(fZero*4),D7
|
||
@L475:
|
||
CLR.W 0(A0,D7.W)
|
||
CLR.W 2(A0,D7.W)
|
||
SUBQ.B #4,D7
|
||
BPL.S @L475
|
||
|
||
;WITH myCanonical,partsTable DO BEGIN
|
||
; j:= 1;
|
||
; positions[positive].start:= 1;
|
||
|
||
@L474:
|
||
MOVEA.L myCanonical(A6),myCanonicalR
|
||
|
||
tst.b formString(myCanonicalR) ; check for empty formatString
|
||
beq.s @emptyFormatString
|
||
|
||
MOVEA.L partsTable(A6),A0
|
||
MOVE.L A0,hold12(A6)
|
||
MOVE.W #1,j(A6)
|
||
|
||
MOVE.L positions(A6),A0
|
||
MOVE.W #1,4*fPositive(A0)
|
||
|
||
IF 1 THEN ; make common code <2/7/88med>
|
||
; CheckForm( positive );
|
||
sf inLiteral(a6) ; clear literal flag <2/7/88med>
|
||
MOVE.B #fPositive,-(A7)
|
||
MOVE.L A6,-(A7)
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
GetSMgrCore procVectR ; setup and call vector <6/17/88ldc>
|
||
move.l sVectCheckForm(procVectR), procVectR
|
||
jsr (procVectR)
|
||
|
||
ELSE
|
||
|
||
JSR CheckForm
|
||
|
||
ENDIF
|
||
|
||
ELSE ; old stuff
|
||
|
||
; FOR i:= 1 TO startLocs[negative]-1 DO BEGIN
|
||
; TranslateToText( formString[i] ); END;
|
||
|
||
MOVE.W (((startLocs+data)+(2*fNegative))(myCanonicalR),D0
|
||
SUBQ.W #1,D0
|
||
MOVE.W D0,hold11(A6)
|
||
MOVEQ #1,iR
|
||
BRA.S @L476
|
||
@L479:
|
||
CLR.W D1
|
||
MOVE.B formString(myCanonicalR,iR.W),D1
|
||
MOVE.W D1,-(A7)
|
||
MOVE.L A6,-(A7)
|
||
JSR TranslateToText
|
||
ADDQ.W #1,iR
|
||
@L476:
|
||
compw hold11(A6),iR
|
||
BLE.S @L479
|
||
|
||
; positions[positive].length:= j-1;
|
||
|
||
@L478:
|
||
MOVE.W j(A6),D0
|
||
SUBQ.W #1,D0
|
||
MOVEA.L positions(A6),A0
|
||
MOVE.W D0,(FVector.length+(fPositive*2))(A0)
|
||
|
||
ENDIF
|
||
|
||
; CheckForm( negative )
|
||
;<3/28/88ldc>
|
||
|
||
sf inLiteral(A6)
|
||
MOVE.B #fNegative,-(A7)
|
||
move.l a6, -(a7)
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
jsr (procVectR)
|
||
|
||
ELSE
|
||
|
||
JSR CheckForm
|
||
|
||
ENDIF
|
||
|
||
|
||
; CheckForm( zero )
|
||
;<3/28/88ldc>
|
||
|
||
sf inLiteral(A6)
|
||
MOVE.B #fZero,-(A7)
|
||
MOVE.L A6,-(A7)
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
jsr (procVectR)
|
||
|
||
ELSE
|
||
|
||
JSR CheckForm
|
||
|
||
ENDIF
|
||
|
||
|
||
; s[0]:= CHR(j-1); END;
|
||
|
||
MOVEA.L outString(A6),A0
|
||
MOVE.W j(A6),D0
|
||
SUBQ.W #1,D0
|
||
MOVE.B D0,(A0)
|
||
|
||
bra.s @exit
|
||
|
||
;<9/7/88ldc> return with empty outString
|
||
|
||
@emptyFormatString
|
||
move.w #fEmptyFormatString, res(a6) ; flag empty format string
|
||
movea.l outString(A6),A0
|
||
move.b #0,(A0) ; set outstring length to zero
|
||
|
||
;IF res <> ORD(formatOk) THEN Format2Str:= res;
|
||
|
||
@exit
|
||
compw #fFormatOK,res(A6)
|
||
BEQ.S @L482
|
||
MOVE.W res(A6),returnValue1(A6)
|
||
@L482:
|
||
MOVEM.L (A7)+,localRegs
|
||
|
||
move #argFrame1, d0 ; for StdUnlink
|
||
bra StdUnlink ; standard exit
|
||
|
||
CheckDebug 'FORM2STR'
|
||
|
||
endp
|
||
|
||
;------------------------------------------------------------
|
||
FormStr2XFrame record {oldA61},decrement
|
||
returnValue1 ds.w 1 ; INTEGER
|
||
argFrameT1 EQU *
|
||
source ds.l 1 ; VAR str255
|
||
myCanonical ds.l 1 ; VAR NumFormatString
|
||
partsTable ds.l 1 ; VAR NumberParts
|
||
xOrig ds.l 1 ; VAR EXTENDED
|
||
selector1 ds.l 1
|
||
argFrame1 EQU argFrameT1-*
|
||
|
||
return1 ds.l 1
|
||
oldA61 ds.l 1
|
||
|
||
possible ds.b 4 ; ARRAY[postive..negative] OF BOOLEAN
|
||
isNeg ds.b 1 ; BOOLEAN
|
||
doPercent ds.b 1 ; BOOLEAN
|
||
going ds.b 1 ; BOOLEAN
|
||
formCount ds.b 1 ; FormatClass
|
||
Fsize ds.w 1 ; INTEGER
|
||
temp ds.w 1 ; INTEGER
|
||
Ssize ds.w 1 ; INTEGER
|
||
rIndex ds.w 1 ; INTEGER
|
||
sIndex ds.w 1 ; INTEGER
|
||
nothing ds.w 1 ; INTEGER
|
||
real ds.b 256 ; str255
|
||
saveSIndex ds.w 1 ; INTEGER
|
||
saveRIndex ds.w 1 ; INTEGER
|
||
saveCIndex ds.w 1 ; INTEGER
|
||
|
||
pastDecimal ds.b 1 ; BOOLEAN
|
||
afterEFormat ds.b 1 ; BOOLEAN <88.09.19ldc>
|
||
|
||
;--------------------------------------------------------
|
||
; used by calls to sane package
|
||
saneEnv ds.w 1 ; SANE Environment
|
||
indexF ds.w 1 ; index to floating pt value returned by str2dec
|
||
prefixF ds.w 1 ; valid prefix
|
||
decRecF ds.b 26 ; decimal record (needs 25 bytes, see Decimal later)
|
||
garbage1 ds.b 6 ; ? (not used explicitly in this file)
|
||
checkFDmask ds.b 1 ; mask for CheckForDigits result
|
||
ds.b 1 ; reserved
|
||
|
||
localFrame1 EQU *
|
||
ENDR
|
||
|
||
;============================================================
|
||
;Procedure MatchingSubString( c: WideChar;
|
||
; var index: integer;
|
||
; ignoreCase: boolean;
|
||
; oldAHf2: address): boolean;
|
||
;============================================================
|
||
; MatchingSubString
|
||
;
|
||
; trashes a0,d0-d2
|
||
; uses/restores a3-a4,d3
|
||
; calls CharComp, which trashes a0,d0-01
|
||
;
|
||
; NOTE: UprString (called by CharComp) now depends on the a5 world,
|
||
; so don't muck around with a5 before calling CharComp! <02/21/89 pke>
|
||
; Actually, UprString is again independent of a5 world, but now we're
|
||
; using LwrString instead, which DOES depend on a5 world. <06/30/89 pke>
|
||
;
|
||
; redefined MatchingSubString to allow case insensitivity. <3/16/88ldc>
|
||
|
||
MatchingSubString proc
|
||
|
||
;------------------------------------------------------------
|
||
MatchingSubStringFrame record {oldA62},decrement
|
||
match ds.w 1 ; BOOLEAN
|
||
argFrameT2 EQU *
|
||
c ds.w 1 ; WideChar
|
||
index ds.l 1 ; VAR INTEGER
|
||
ignoreCase ds.w 1 ; boolean
|
||
oldA6f2 ds.l 1
|
||
argFrame2 EQU argFrameT2-*
|
||
|
||
return2 ds.l 1
|
||
oldA62 ds.l 1
|
||
localFrame2 EQU *
|
||
ENDR
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
|
||
localRegs reg d3/a3/A4 ; don't need to save a5 <02/21/89 pke>
|
||
|
||
indexR EQU A3
|
||
bumpIndexR EQU d3
|
||
ff EQU A4
|
||
|
||
|
||
;============================================================
|
||
WITH FormStr2XFrame,MatchingSubStringFrame, SMgrRecord
|
||
|
||
LINK A6,#localFrame2
|
||
MOVEM.L localRegs,-(A7)
|
||
MOVEA.L index(A6),indexR ;make use of these lazy regs
|
||
MOVEA.L oldA6f2(A6),ff
|
||
MOVE.W (indexR),D2 ;compute address of source[index]
|
||
MOVEA.L source(ff),A0
|
||
ADDA.W D2,A0
|
||
SF match(A6) ;default with no match
|
||
MOVE.W c(A6),D0 ;put c somewhere useful
|
||
BEQ.S @done ;but leave if it's null
|
||
compw #$FF,D0 ;if it's a double-byte character then it'll …
|
||
BLS.S @singleByte ;…be greater than $FF
|
||
|
||
;set up for CharComp of two bytes
|
||
compw Ssize(ff),D2 ;verify that we're not beyond the end of the string
|
||
bge.s @done ; >= for 2 bytes
|
||
moveq #2,bumpIndexR ;bump index by two for two byte char
|
||
move.b (a0)+,d1 ;get one byte
|
||
lsl.w #8, d1 ;shift it to upper half of word
|
||
move.b (a0),d1 ;get the next
|
||
BRA.S @doCompare
|
||
|
||
@singleByte:
|
||
compw Ssize(ff),D2 ;again, check overflow
|
||
BGT.S @done ;note different boundary
|
||
clr.w d1
|
||
move.b (a0), d1 ;
|
||
moveq #1, bumpIndexR ;match will bump index by one
|
||
|
||
@doCompare
|
||
tst.w ignoreCase(a6)
|
||
beq.s @caseSensitive
|
||
clr.w -(a7)
|
||
move.w d0, -(a7)
|
||
move.w d1, -(a7)
|
||
jsr CharComp ;if not CharComp(c, source[index]) then
|
||
not.b (a7)+ ;match := false
|
||
bra.s @checkResult
|
||
|
||
@caseSensitive
|
||
cmp.w d0, d1 ;if c <> source[index] then
|
||
;equal := false
|
||
@checkResult
|
||
bne.s @done
|
||
ADD.W bumpIndexR,(indexR) ;else advance index by appropriate value
|
||
st match(A6) ;equal := true
|
||
@done
|
||
MOVEM.L (A7)+,localRegs
|
||
|
||
move #argFrame2, d0 ; for StdUnlink
|
||
bra StdUnlink ; standard exit
|
||
|
||
CheckDebug 'MATCHSUB'
|
||
|
||
ENDWITH
|
||
ENDP
|
||
|
||
;============================================================
|
||
; matchingBlocks
|
||
;
|
||
; trashes a0,d0 (,d1-d2)
|
||
; uses/restores a3,a4,d7, and a2 (was a5) for buildLevel >= 2
|
||
; calls MatchingSubString, which trashes a0,d0-d2
|
||
; called by Cond
|
||
;
|
||
matchingBlocks proc
|
||
|
||
;------------------------------------------------------------
|
||
matchingBlocksFrame record {oldA62},decrement
|
||
returnValue2 ds.w 1 ; BOOLEAN
|
||
argFrameT2 EQU *
|
||
c ds.l 1 ; VAR WideCharArr
|
||
oldA6f2 ds.l 1
|
||
argFrame2 EQU argFrameT2-*
|
||
|
||
return2 ds.l 1
|
||
oldA62 ds.l 1
|
||
|
||
j ds.w 1 ; INTEGER
|
||
i ds.w 1 ; INTEGER
|
||
garbage2 ds.b 2 ; ?
|
||
localFrame2 EQU *
|
||
ENDR
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
|
||
localRegs reg D7/a2-a4 ; need a5 world here <02/21/89 pke>
|
||
|
||
ff EQU A3
|
||
cR EQU A4
|
||
|
||
;============================================================
|
||
WITH FormStr2XFrame,matchingBlocksFrame, SMgrRecord
|
||
|
||
LINK A6,#localFrame2
|
||
MOVEM.L localRegs,-(A7)
|
||
MOVEA.L oldA6f2(A6),ff ;outer frame pointer
|
||
MOVEA.L c(A6),cR ;registerize c's address
|
||
MOVE.W sIndex(ff),j(A6) ;j is a provisional pointer
|
||
SF returnValue2(A6) ;assume the worse
|
||
MOVE.W WideCharArr.size(cR),D7 ;loop to c.size
|
||
BLT.S @out ;negative size means the array is empty
|
||
LEA WideCharArr.data(cr),cR ;retrieve beginning of character array
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
; GetSMgrCore a5 ; setup for vector call <6/17/88ldc>
|
||
; move.l sVectMatchingSubString(a5), a5 ; before entering loop
|
||
GetSMgrCore a2 ; setup for vector call <02/21/89 pke>
|
||
move.l sVectMatchingSubString(a2), a2 ; before entering loop
|
||
|
||
ENDIF
|
||
|
||
@eqLoop:
|
||
CLR.W -(A7) ;return space
|
||
MOVE.W (cR)+,-(A7) ;push the next character
|
||
PEA j(A6) ;and our provisional index
|
||
; added boolean switch to ignore case so 'e' and 'E' are
|
||
;treated equally <3/16/88ldc>
|
||
move.w #1,-(a7) ;ignoreCase := true
|
||
MOVE.L ff,-(A7) ;not to mention the proper frame pointer
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
; jsr (a5) ; now a vector
|
||
jsr (a2) ; now a vector <02/21/89 pke>
|
||
|
||
ELSE
|
||
|
||
JSR matchingSubString
|
||
|
||
ENDIF
|
||
|
||
MOVE.B (A7)+,D0 ;was it a match?
|
||
DBEQ D7,@eqLoop ;done if not or if we ran out of chars
|
||
BEQ.S @out
|
||
|
||
ST returnValue2(A6) ;we matched so say so
|
||
MOVE.W j(A6),sIndex(a3) ;the provisional index was real after all
|
||
@out:
|
||
MOVEM.L (A7)+,localRegs
|
||
|
||
move #argFrame2, d0 ; for StdUnlink
|
||
bra StdUnlink ; standard exit
|
||
|
||
CheckDebug 'MATCHBLO'
|
||
|
||
ENDWITH
|
||
endp
|
||
|
||
;============================================================
|
||
; CheckForDigits
|
||
;
|
||
; trashes a0-a1,d0-d1 (,d2)
|
||
; uses/restores a2-a4,d6-d7
|
||
; calls matchingSubString, which trashes a0,d0-d2
|
||
;
|
||
CheckForDigits proc
|
||
|
||
;------------------------------------------------------------
|
||
CheckForDigitsFrame record {oldA62},decrement
|
||
returnValue2 ds.w 1 ; BOOLEAN
|
||
argFrameT2 EQU *
|
||
oldA6f2 ds.l 1
|
||
argFrame2 EQU argFrameT2-*
|
||
|
||
return2 ds.l 1
|
||
oldA62 ds.l 1
|
||
|
||
k ds.w 1 ; INTEGER
|
||
ch ds.w 1 ; CHAR
|
||
matching ds.w 1 ; BOOLEAN
|
||
garbage2 ds.b 8 ; ?
|
||
localFrame2 EQU *
|
||
ENDR
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
|
||
localRegs reg D5-D7/A2-A4 ; now need D5 (didn't need D4) <05/22/89 pke>
|
||
|
||
ff EQU a4
|
||
realR EQU a2
|
||
matchingR EQU d6
|
||
kR EQU d7
|
||
partsTableR EQU a3
|
||
|
||
;============================================================
|
||
WITH FormStr2XFrame,CheckForDigitsFrame,FormatStringPriv,NumberParts, SMgrRecord
|
||
|
||
LINK A6,#localFrame2
|
||
MOVEM.L localRegs,-(A7)
|
||
MOVEA.L oldA6f2(A6),ff
|
||
|
||
SF D5 ;assume the worst
|
||
|
||
MOVEA.L myCanonical(ff),A1 ;we only need this once
|
||
MOVEA.L partsTable(ff),partsTableR ;make use of the empty regs
|
||
LEA real(ff),realR
|
||
ADD.W rIndex(ff),realR ;point ourself to our current index
|
||
MOVEA.L source(ff),A0 ;we only need this one once, too
|
||
MOVE.W sIndex(ff),D0 ;check to see if this is a digit
|
||
MOVE.B 0(A0,D0.W),D1
|
||
compb #'0',D1
|
||
BLT.S @noDigit
|
||
compb #'9',D1
|
||
BGT.S @noDigit
|
||
MOVE.B D1,(realR) ;but if it is a digit, move it into the current string
|
||
ADDQ.W #1,rIndex(ff) ;and increment all our indexes
|
||
ADDQ.W #1,sIndex(ff)
|
||
|
||
ST D5 ;
|
||
CMP.B #'0',D1 ;
|
||
BEQ.S @doneRealZeroTest ;
|
||
MOVE.B #$7F,D5 ;
|
||
@doneRealZeroTest:
|
||
|
||
BRA.S @out
|
||
@noDigit:
|
||
MOVE.B formCount(ff),D0 ;we'll give it a second chance…
|
||
EXT.W D0 ;…by checking against the alternative digits
|
||
ADD.W D0,D0
|
||
BTST #fIsAltNum,Flags(A1,D0.W) ;do we even allow alternate digits?
|
||
BEQ.S @out ;nope, so forget it
|
||
SF matchingR ;otherwise, try matching against alternates
|
||
MOVE.W #9,kR ;k is the loop counter
|
||
LEA AltNumTable.data(partsTableR),partsTableR ; <2-25-88med.ldc>
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
; GetSMgrCore a5 ; setup for vector call <6/18/88ldc>
|
||
; move.l sVectMatchingSubString(a5), a5
|
||
GetSMgrCore a1 ; ok to reuse a1, can't use a5 <02/21/89 pke>
|
||
move.l sVectMatchingSubString(a1), a1
|
||
|
||
ENDIF
|
||
|
||
@altLoop:
|
||
CLR.W -(A7) ; return space
|
||
MOVE.W (partsTableR)+,-(A7) ; push the current character
|
||
PEA sIndex(ff) ; and the index into the source string
|
||
clr.w -(a7) ; case sensitive is cheaper
|
||
MOVE.L ff,-(A7) ; oh, don't forget the silly frame pointer
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
; jsr (a5) ; call the vector
|
||
jsr (a1) ; <02/21/89 pke>
|
||
|
||
ELSE
|
||
|
||
JSR matchingSubString
|
||
|
||
ENDIF
|
||
|
||
MOVE.B (A7)+,matchingR ;did we match?
|
||
DBNE kR,@altLoop ;yes, fall through, or no, dbra
|
||
BEQ.S @out ;just checking
|
||
|
||
;; MOVE.B #'9',(realR) ;digit:= '9'-k
|
||
;; SUB.W kR,(realR)
|
||
move.l #'9',d0 ; digit := '9'-k <2-25-88med.ldc>
|
||
sub.b kR,d0 ; subtract <2-25-88med.ldc>
|
||
move.b d0,(realR) ; store in array <2-25-88med.ldc>
|
||
|
||
ADDQ.W #1,rIndex(ff) ;update the index
|
||
|
||
ST D5 ;
|
||
CMP.B #'0',D0 ;
|
||
BEQ.S @doneAltZeroTest ;
|
||
MOVE.B #$7F,D5 ;
|
||
@doneAltZeroTest:
|
||
|
||
@out:
|
||
|
||
MOVE.B D5,returnValue2(A6) ;
|
||
|
||
MOVEM.L (A7)+,localRegs
|
||
UNLK A6
|
||
MOVE.L (A7)+,(A7)
|
||
RTS
|
||
|
||
CheckDebug 'CHECKDIG'
|
||
ENDWITH
|
||
endp
|
||
|
||
;------------------------------------------------------------
|
||
ExpMatchingFrame record {oldA62},decrement
|
||
returnValue2 ds.w 1 ; BOOLEAN
|
||
argFrameT2 EQU *
|
||
plusData ds.l 1 ; VAR WideCharArr
|
||
oldA6f2 ds.l 1
|
||
argFrame2 EQU argFrameT2-*
|
||
|
||
return2 ds.l 1
|
||
oldA62 ds.l 1
|
||
garbage2 ds.b 4
|
||
localFrame2 EQU *
|
||
ENDR
|
||
|
||
;============================================================
|
||
; Cond
|
||
;
|
||
; trashes a0,d0 (,d1-d2)
|
||
; uses/restores a2-a4,d3-d4, plus d5 for buildLevel >= 1, a5 otherwise
|
||
; calls matchingBlocks, which trashes a0,d0-d2
|
||
;
|
||
Cond proc
|
||
|
||
;------------------------------------------------------------
|
||
CondFrame record {oldA63},decrement
|
||
argFrameT3 EQU *
|
||
a ds.l 1 ; VAR WideCharArr
|
||
b ds.l 1 ; VAR WideCharArr
|
||
aSign ds.b 1 ; CHAR
|
||
ALIGN 2
|
||
bSign ds.b 1 ; CHAR
|
||
ALIGN 2
|
||
oldA6f3 ds.l 1
|
||
argFrame3 EQU argFrameT3-*
|
||
|
||
return3 ds.l 1
|
||
oldA63 ds.l 1
|
||
|
||
localFrame3 EQU *
|
||
ENDR
|
||
|
||
;============================================================
|
||
WITH FormStr2XFrame,ExpMatchingFrame,CondFrame
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
localRegs reg D3-D5/A2-A4 ; <02/21/89 pke>
|
||
fff EQU a3 ; <02/21/89 pke>
|
||
|
||
ff EQU a4
|
||
realR EQU a2
|
||
abR EQU d4
|
||
signR EQU d3
|
||
|
||
LINK A6,#localFrame3
|
||
MOVEM.L localRegs,-(SP)
|
||
MOVEA.L oldA6f3(A6),ff
|
||
MOVE.L oldA6f2(ff),fff ;you like these nested procs too?
|
||
SF returnValue2(ff)
|
||
LEA real(fff),realR ;this is the real# string we're dealing with
|
||
ADD.W rIndex(fff),realR ;and this is how far into it we are
|
||
MOVE.B aSign(A6),signR ;and we sort of need to know its sexual preference
|
||
MOVE.L a(A6),abR ;check against one version of the exponent
|
||
|
||
moveq #1,d5 ;set firstTime flag <02/21/89 pke>
|
||
|
||
@compare:
|
||
CLR.W -(A7) ;return space
|
||
MOVE.L abR,-(A7) ;push whatever we are comparing
|
||
MOVE.L fff,-(A7) ;and the frame pointer
|
||
JSR matchingBlocks
|
||
MOVE.B (A7)+,D0 ;how'd we do?
|
||
BNE.S @matched ;that's a sigh of relief
|
||
|
||
tst.l d5 ; <02/21/89 pke>
|
||
beq @out ; <02/21/89 pke>
|
||
|
||
@take2:
|
||
MOVE.B bSign(A6),signR ;try matching against the other flavor of exponent
|
||
MOVE.L b(A6),abR
|
||
|
||
moveq #0,d5 ;not firstTime <02/21/89 pke>
|
||
|
||
BRA.S @compare
|
||
@matched:
|
||
MOVE.B #'E',(realR)+ ;the canonical 'E'
|
||
MOVE.B signR,(realR) ;and whatever sign we need
|
||
ADDQ.W #2,rIndex(fff) ;update the index
|
||
ST returnValue2(ff) ;and brag about the results
|
||
@out:
|
||
MOVEM.L (A7)+,localRegs
|
||
|
||
move #argFrame3, d0 ; for StdUnlink
|
||
bra StdUnlink ; standard exit
|
||
|
||
CheckDebug 'COND '
|
||
ENDWITH
|
||
endp
|
||
|
||
;============================================================
|
||
; ExpMatching
|
||
;
|
||
; trashes a0,a1,d0
|
||
; uses/restores a3,a4
|
||
; calls Cond, which trashes a0,d0-d2
|
||
;
|
||
ExpMatching func
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
localRegs reg A3/A4
|
||
ff EQU a3
|
||
partsTableR EQU a4
|
||
|
||
;============================================================
|
||
WITH FormStr2XFrame,ExpMatchingFrame,NumberParts,FormatStringPriv, SMgrRecord
|
||
|
||
LINK A6,#localFrame2
|
||
MOVEM.L localRegs,-(A7)
|
||
MOVEA.L oldA6f2(A6),ff
|
||
MOVEA.L partsTable(ff),partsTableR ;WITH partsTable
|
||
LEA PeMinus(partsTableR),A1
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
GetSMgrCore partsTableR ;recycle a4 & setup for vector call
|
||
move.l sVectCond(partsTableR), partsTableR ; <6/21/88ldc>
|
||
|
||
ENDIF
|
||
|
||
MOVEA.L plusData(A6),A0 ;Check which of E+ and E- is larger…
|
||
MOVE.W WideCharArr.size(A0),D0 ;…it's important because one could be a substring of the other
|
||
compw WideCharArr.size(A1),D0
|
||
BLT.S @bigEMinus
|
||
MOVE.L A0,-(A7)
|
||
MOVE.L A1,-(A7)
|
||
MOVE.L #((('-')<<16)+'+'),-(A7) ;push + then -
|
||
MOVE.L A6,-(A7)
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
jsr (partsTableR) ; call vect <6/17/88ldc>
|
||
ELSE
|
||
JSR Cond ;try matching against exponents
|
||
ENDIF
|
||
|
||
BRA.S @out
|
||
@bigEMinus:
|
||
MOVE.L A1,-(A7)
|
||
MOVE.L A0,-(A7)
|
||
MOVE.L #((('+')<<16)+'-'),-(A7) ;push - then +
|
||
MOVE.L A6,-(A7)
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
jsr (partsTableR) ; call vect <6/17/88ldc>
|
||
ELSE
|
||
JSR Cond
|
||
ENDIF
|
||
|
||
@out:
|
||
MOVEM.L (A7)+,localRegs
|
||
|
||
move #argFrame2, d0 ; for StdUnlink
|
||
bra StdUnlink ; standard exit
|
||
|
||
CheckDebug 'EXPMATCH'
|
||
ENDWITH
|
||
endp
|
||
|
||
;============================================================
|
||
; xFormStr2X
|
||
;
|
||
; trashes a0-a1,d0-d2
|
||
; uses/restores a2-a4,d3-d7
|
||
; calls MatchingSubString trashes a0,d0-d2
|
||
; CheckForDigits trashes a0-a1,d0-d2
|
||
; ExpMatching trashes a0,a1,d0
|
||
; CharComp here trashes a0,d0-d1
|
||
; NextFormatClass changes d0
|
||
; _CharByte (may trash a0-a1,d0-d2)
|
||
; FPSTR2DEC (_PACK7)
|
||
; FDEC2X (_FP68K)
|
||
; FDIVX (_FP68K)
|
||
;
|
||
; NOTE: UprString (called by CharComp) now depends on the a5 world,
|
||
; so don't muck around with a5 before calling CharComp! <02/21/89 pke>
|
||
; Actually, UprString is again independent of a5 world, but now we're
|
||
; using LwrString instead, which DOES depend on a5 world. <06/30/89 pke>
|
||
;
|
||
xFormStr2X proc
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
localRegs reg D3-D7/A2-A5 ; a5 not used, change to not save <02/21/89 pke>
|
||
|
||
myCanonicalR EQU a3
|
||
partsTableR EQU a4
|
||
formCountR EQU a2
|
||
cIndexR EQU d7
|
||
tempR EQU d6
|
||
goingR EQU d5
|
||
cR EQU d4
|
||
saveCIndexR EQU d3
|
||
|
||
|
||
;============================================================
|
||
WITH FormStr2XFrame,FormatStringPriv,NumberParts, SMgrRecord
|
||
|
||
LINK A6,#localFrame1
|
||
MOVEM.L localRegs,-(A7)
|
||
SF doPercent(A6) ;do a bunch of initializations
|
||
MOVEA.L source(A6),A0 ;move the source length into local space
|
||
CLR.W D0
|
||
MOVE.B (A0),D0
|
||
MOVE.W D0,Ssize(A6)
|
||
MOVE.B #'1',(real+1)(A6) ;assume '1' as a default in case there are no digits on input
|
||
MOVEA.L myCanonical(A6),myCanonicalR
|
||
; test for empty format string <9/7/88ldc>
|
||
MOVEA.L partsTable(A6),partsTableR
|
||
LEA formCount(A6),formCountR
|
||
CLR.W D0 ;move the length of the form string into local space
|
||
MOVE.B formString(myCanonicalR),D0
|
||
MOVE.W D0,Fsize(A6)
|
||
|
||
SF goingR ; needs initialization <9/7/88ldc>
|
||
|
||
SF possible+fNegative(A6) ;more obvious initializations
|
||
SF possible+fZero(A6)
|
||
ST possible+fPositive(A6)
|
||
MOVE.W #fPositive,(formCountR)
|
||
|
||
BTST.B #fExists,(flags+2*fPositive)(myCanonicalR)
|
||
BEQ @bestGuess
|
||
|
||
; replaced #1 with fFormatOK <2/23/88:ldc>
|
||
MOVE.W #fFormatOK, returnValue1(A6)
|
||
|
||
MOVEQ #1,D0
|
||
MOVE.W D0,sIndex(A6)
|
||
MOVE.L D0,cIndexR
|
||
MOVE.W D0,rIndex(A6)
|
||
SF pastDecimal(a6)
|
||
|
||
ST checkFDmask(A6) ;any digit is OK
|
||
|
||
CLR.W saveCIndexR ;saveCIndex is for backtracking when we have optional digits
|
||
MOVE.W (((tokMinusSign-tokLeftQuote)*2)+data)(partsTableR),D0
|
||
BSR @matchSS ;check if the very first character is a minus sign
|
||
MOVE.B D0,isNeg(A6) ;and if it is, say so
|
||
|
||
|
||
move.w FSize(a6), d0 ; get format string size <9/7/88ldc>
|
||
beq @emptyFormatString ; best guess
|
||
compw d0,cIndexR ;make sure we've got something in the format string
|
||
|
||
SLE goingR
|
||
MOVE.W sIndex(A6),D1 ;and also in the source string
|
||
compw Ssize(A6),D1
|
||
SLE D1
|
||
AND.B D1,goingR
|
||
@whileGoing:
|
||
MOVE.B goingR,D0
|
||
BEQ @doneGoing
|
||
CLR.W cR
|
||
|
||
MOVE.B formString(myCanonicalR,cIndexR.W),cR ;update c to next format symbol
|
||
compw #(tokMaxSymbols+1),cR ;upper limit of control codes
|
||
BGE @noJump
|
||
MOVE.W cR,D0
|
||
SUBQ.W #tokLeader,D0 ;upper limit of jump table
|
||
BMI @endJump
|
||
compw #(tokEMinus-tokLeader),D0
|
||
BGT @endJump
|
||
ADD.W D0,D0
|
||
MOVE.W @jTab(D0.W),D0
|
||
JMP *+2(D0.W)
|
||
@jTab:
|
||
DC.W @leads-@jTab+2, @nonLeads-@jTab+2, @leads-@jTab+2
|
||
DC.W @others-@jTab+2, @others-@jTab+2, @others-@jTab+2
|
||
DC.W @others-@jTab+2, @empty-@jTab+2, @empty-@jTab+2
|
||
DC.W @empty-@jTab+2, @decPoint-@jTab+2, @ePlus-@jTab+2
|
||
DC.W @eMinus-@jTab+2
|
||
|
||
@leads:
|
||
BSR @checkFD ;check for digit
|
||
BNE.S @leadMatch ;sure enough got one
|
||
MOVE.W cR,D0 ;if we didn't get one then check for the lead character
|
||
ADD.W D0,D0
|
||
MOVE.W -(tokLeftQuote*2)+data(partsTableR,D0.W),D0
|
||
BSR.S @matchSS
|
||
BEQ @notThisForm ;if we didn't get one then we just aren't a match
|
||
@leadMatch:
|
||
BRA @mergeJump
|
||
|
||
@nonLeads:
|
||
TST.W saveCIndexR ;if this is the first of a string of nonLeads,
|
||
BNE.S @noReset ;then we need to fill the state holders.
|
||
MOVE.W cIndexR,saveCIndexR ;these variables allow handling optional digits
|
||
MOVE.W rIndex(A6),saveRIndex(A6)
|
||
MOVE.W sIndex(A6),saveSIndex(A6)
|
||
@noReset:
|
||
BSR.S @checkFD ;check for a digit
|
||
|
||
BEQ @notThisForm ;if we didn't get one then we just aren't a match
|
||
|
||
BRA @mergeJump ;and finish
|
||
|
||
@decPoint:
|
||
|
||
ST pastDecimal(a6) ;pastDecimal is necessary info when handling optional digits
|
||
CLR.W saveCIndexR ;start anew on the optional digit state
|
||
; added data offset <3/14/88ldc>
|
||
MOVE.W (((tokDecPoint-tokLeftQuote)*2)+data)(partsTableR),D0
|
||
BSR.S @matchSS ;match against a decimal point
|
||
|
||
BEQ @notThisForm ;(or at least try, that is)
|
||
|
||
MOVE.W rIndex(A6),D0 ;insert a decimal point into the real# string
|
||
LEA real(A6),A0
|
||
MOVE.B #'.',0(A0,D0.W)
|
||
ADDQ.W #1,rIndex(A6) ;update the real# string index
|
||
BRA.S @endJump
|
||
|
||
@others:
|
||
MOVE.W cR,D0 ;try matching source string against format string
|
||
ADD.W D0,D0
|
||
MOVE.W -(tokLeftQuote*2)+data(partsTableR,D0.W),D0
|
||
BSR.S @matchSS
|
||
BEQ.S @notThisForm ;failure if no match
|
||
|
||
BRA @mergeJump
|
||
|
||
@ePlus:
|
||
LEA PePlus(partsTableR),A0
|
||
BSR.S @expM ;match against ePlus
|
||
BEQ.S @notThisForm ;failure if no match
|
||
; changed branch from @mergeJump to @mergeExp <1/23/88drs>
|
||
BRA.S @mergeExp
|
||
|
||
@eMinus:
|
||
LEA PeMinusPlus(partsTableR),A0
|
||
JSR @expM ;match against eMinusPlus
|
||
BEQ.S @notThisForm
|
||
; inserted @mergeExp and following two lines to correct bug. <1/23/88drs>
|
||
;After the exponent is reached, the parsing algorithm should treat
|
||
;exponent digits as if they were pre-decimal significand.
|
||
@mergeExp:
|
||
MOVEQ #0,SaveCIndexR ;reset saveCIndex
|
||
CLR.B pastDecimal(A6)
|
||
|
||
ST checkFDmask(A6) ;any digit is OK as exponent
|
||
|
||
@endJump:
|
||
@empty:
|
||
BRA.S @mergeJump
|
||
|
||
@matchSS: ;standard module for calling matchingSubString
|
||
CLR.W -(A7) ;room for return parameter
|
||
MOVE.W D0,-(A7) ;register based parameter to matchSS
|
||
PEA sIndex(A6) ;position into the source
|
||
clr.w -(a7) ;case sensitive is cheaper
|
||
MOVE.L A6,-(A7) ;the ubiquitous frame pointer
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
GetSMgrCore a0 ; set up for vector call <6/18/88ldc>
|
||
move.l sVectMatchingSubString(a0), a0
|
||
jsr (a0) ; call it <6/18/88ldc>
|
||
|
||
ELSE
|
||
|
||
JSR matchingSubString
|
||
|
||
ENDIF
|
||
|
||
MOVE.B (A7)+,D0 ;result is passed back in D0 (and SR)
|
||
RTS
|
||
|
||
@checkFD:
|
||
CLR.W -(A7) ;common call to CheckForDigits
|
||
MOVE.L A6,-(A7) ;no parameters; only frame pointer
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
GetSMgrCore a0 ; setup for vector call
|
||
move.l sVectCheckForDigits(a0), a0 ; call vect <6/17/88ldc>
|
||
jsr (a0)
|
||
|
||
ELSE
|
||
|
||
JSR CheckForDigits ; This was commented out; shouldn't be.
|
||
; fixed <1/31/89 pke>
|
||
ENDIF
|
||
|
||
MOVE.B (A7)+,D0
|
||
|
||
AND.B checkFDmask(A6),D0
|
||
|
||
RTS ;result in D0 (and SR)
|
||
;------------------------------------------------------------------------------------
|
||
@expM:
|
||
CLR.W -(A7) ;common call to expMatching
|
||
MOVE.L A0,-(A7) ;which exponent is passed here in A0
|
||
MOVE.L A6,-(A7) ;frame pointer again
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
GetSMgrCore a0 ; intlSpec for vector
|
||
move.l sVectExpMatching(a0), a0 ; call vector <6/17/88ldc>
|
||
jsr (a0) ; <6/21/88ldc>
|
||
|
||
ELSE
|
||
|
||
JSR ExpMatching
|
||
|
||
ENDIF
|
||
|
||
MOVE.B (A7)+,D0 ;result in D0 (and SR)
|
||
RTS
|
||
;------------------------------------------------------------------------------------
|
||
|
||
@notThisForm: ;common entry for failed match:
|
||
MOVE.B (FormCountR),D0 ;tentatively declare that the source doesn't match format
|
||
EXT.W D0
|
||
CLR.B possible(A6,D0.W) ;possible[formCount] := FALSE;
|
||
BRA.S @mergeJump
|
||
|
||
@noJump:
|
||
;check source text against form string
|
||
; convert form string and c to upper case before comparison <3/15/88ldc>
|
||
;
|
||
clr.w -(a7)
|
||
move.w cR, -(a7)
|
||
movea.l source(A6),A0
|
||
adda.w sIndex(a6),A0
|
||
move.b (a0), d0
|
||
move.w d0, -(a7)
|
||
jsr CharComp ;if not CharComp(source[sIndex], c) then
|
||
tst.b (a7)+
|
||
beq.S @notThisForm ;possible[formCount] := FALSE
|
||
ADDQ.W #1,sIndex(A6) ;otherwise increment source pointer
|
||
|
||
@mergeJump:
|
||
MOVE.B (FormCountR),D0;the beginning of the next format in the format string…
|
||
JSR NextFormatClass ;…is important enough to dedicate a register to
|
||
ADD.W D0,D0
|
||
MOVE.W startLocs(myCanonicalR,D0.W),tempR
|
||
MOVE.B (FormCountR),D1 ;we'll need formcount in a moment
|
||
EXT.W D1 ;as an integer, that is
|
||
MOVE.W sIndex(A6),D0 ;if we've ran out of source but not format string…
|
||
compw Ssize(A6),D0 ;…then potentially we don't match
|
||
BLE.S @stillMatch
|
||
MOVE.W tempR,D0
|
||
SUBQ.W #1,D0
|
||
compw cIndexR,D0
|
||
BLE.S @stillMatch
|
||
SF possible(A6,D1.W) ;the format string was indeed too long
|
||
@stillMatch:
|
||
TST.B possible(A6,D1.W) ;now check if we provisionally don't match
|
||
BNE @mergeMatch
|
||
|
||
; Changed testing sequence slightly. <1/23/88drs>
|
||
;We need to drop into this code section whenever pastDecimal also.
|
||
|
||
TST.B pastDecimal(a6) ;this gets into complex checks about whether…
|
||
BNE.S @mergeDecCheck ;…we really match or not after provisionally failing
|
||
TST.W saveCIndexR ;if saveCIndex is zero then there were no optional…
|
||
BNE.S @notPastDecimal ;…digits, and we definitely don't match
|
||
|
||
BRA @mergeMatch ;final decision of no match
|
||
|
||
@mergeDecCheck:
|
||
MOVE.W tempR,saveCIndexR ;push saveCIndex to end of format string for now
|
||
|
||
clr.b afterEFormat(a6) ; assume before the exponetial format <88.09.19ldc>
|
||
|
||
@pdLoop: ;this loop forgives material between optional digits
|
||
compw tempR,cIndexR ;make sure we're not beyond end of format string
|
||
BGE.S @setTrue ;and if we are, then we actually did match
|
||
MOVE.W cIndexR,D1 ;see if the next format string code is a nonLeader
|
||
ADDQ.W #1,D1
|
||
CMP.B #tokNonLeader,formString(myCanonicalR,cIndexR.W)
|
||
|
||
BNE.S @testEFormat ;ignore if not, but first check for EFormat <88.09.19ldc>
|
||
|
||
; added 3 lines to fix bug. <1/23/88drs>
|
||
;If pastDecimal then the only time it doesn't match is when there is
|
||
;something after the last nonLeader
|
||
|
||
MOVE.B (FormCountR),D0 ;go ahead and decide that a match is still possible
|
||
EXT.W D0
|
||
ST possible(A6,D0.W)
|
||
|
||
|
||
; added following to allow acceptance of 3.0E+0 with #.##E+# format <88.09.19ldc>
|
||
|
||
tst.b afterEFormat(a6) ; skip non-leads after the EFormat
|
||
bne.s @mergePdLoop
|
||
|
||
MOVE.W D1,saveCIndexR ;and set save index to this nonLeader
|
||
BRA.s @mergePdLoop ; <88.09.19ldc>
|
||
|
||
; are we past the exponential form? Need this test to accept 3.0E+0 with #.##E+# format. <88.09.19ldc>
|
||
|
||
@testEFormat
|
||
cmp.b #tokEPlus, formString(myCanonicalR,cIndexR.W) ; <88.09.19ldc>
|
||
beq.s @setAfterE ; <88.09.19ldc>
|
||
cmp.b #tokEMinus, formString(myCanonicalR,cIndexR.W) ; <88.09.19ldc>
|
||
bne.s @mergePdLoop ; <88.09.19ldc>
|
||
@setAfterE
|
||
st afterEFormat(a6) ; <88.09.19ldc>
|
||
ST checkFDmask(A6) ;any digit is OK after exp <05/22/89 pke>
|
||
|
||
@mergePdLoop:
|
||
MOVE.W D1,cIndexR ;advance the format string index
|
||
BRA.S @pdLoop
|
||
|
||
@notPastDecimal:
|
||
ADDQ.W #1,saveCIndexR ;gobble up all but leaders, exps, decPoints, pos/neg
|
||
compw tempR,saveCIndexR ;but make sure we've not reached next format
|
||
BGE.S @setTrue ;if we have, then we match
|
||
MOVE.B formString(myCanonicalR,saveCIndexR.W),D0
|
||
CMP.B #tokMaxSymbols,D0 ;check for ascii character…
|
||
BGT.S @notPastDecimal ;…and continue looping if it is one
|
||
MOVE.L #((((((((1<<tokNonLeader)++(1<<tokLeader))++(1<<tokZeroLead))++(1<<tokDecPoint))++(1<<tokPlusSign))++(1<<tokMinusSign))++(1<<tokEPlus))++(1<<tokEMinus)),D1
|
||
BTST.L D0,D1 ;is it any of those listed above?
|
||
BEQ.S @notPastDecimal ;no, so continue looping
|
||
|
||
@setTrue:
|
||
compw saveCIndexR,tempR ;make sure we haven't overflowed
|
||
BLE.S @fMerge
|
||
MOVE.W saveCIndexR,cIndexR ;since we matched, set position in format string
|
||
MOVE.B (FormCountR),D0 ;and set the possible flag back to true
|
||
EXT.W D0
|
||
ST possible(A6,D0.W)
|
||
TST.B pastDecimal(a6) ;if we're not past the decimal…
|
||
BNE.S @fMerge
|
||
CLR.W saveCIndexR ;…then reset the status keepers
|
||
MOVE.W saveSIndex(A6),sIndex(A6)
|
||
MOVE.W saveRIndex(A6),rIndex(A6)
|
||
BRA.S @fMerge
|
||
|
||
@mergeMatch:
|
||
ADDQ.W #1,cIndexR ;update cIndex
|
||
@fMerge: ;this entry avoids update; it already happened
|
||
MOVE.B (FormCountR),D0 ;now check if format string is done but source isn't
|
||
EXT.W D0
|
||
compw cIndexR,tempR
|
||
BGT.S @cMerge ;no, format is not done
|
||
MOVE.W sIndex(A6),D1
|
||
compw Ssize(A6),D1
|
||
BGT.S @cMerge ;yes, format is done, but so is source
|
||
SF possible(A6,D0.W) ;this source just doesn't match
|
||
|
||
@cMerge:
|
||
MOVE.B possible(A6,D0.W),D1 ;so, well, did we finally match or not
|
||
BNE.S @mergeMTest
|
||
compb #fZero,(FormCountR) ;if this is zero format, we're done
|
||
BNE.S @zMerge ;otherwise give it another try with next format
|
||
SF goingR ;none of the formats match
|
||
BRA.S @mergeMTest
|
||
@zMerge:
|
||
CLR.B isNeg(A6) ;increment the format counter and reset…
|
||
MOVE.B (FormCountR),D0 ;…so we can try matching against next format
|
||
EXT.W D0
|
||
ADDQ.W #1,D0
|
||
MOVE.B D0,(FormCountR)
|
||
MOVE.W D0,D1 ;but if the next format doesn't exist,…
|
||
ADD.W D0,D0 ;…we're up a creek
|
||
BTST #fExists,flags(myCanonicalR,D0.W)
|
||
BEQ.S @noNext
|
||
MOVEQ #1,D2 ;reset all the status and flags
|
||
|
||
CMP.W #fZero,D1
|
||
BNE.S @nonZeroSetup
|
||
; MOVE.B #'0',(real+1)(A6) ;<don't use form-dependent default for now>
|
||
MOVE.B #$80,checkFDmask(A6) ;for digits, accept only 0 until exponent
|
||
BRA.S @doneSpecialSetup ;
|
||
@nonZeroSetup:
|
||
; MOVE.B #'1',(real+1)(A6) ;<don't use form-dependent default for now>
|
||
ST checkFDmask(A6) ;
|
||
@doneSpecialSetup:
|
||
MOVE.B #'1',(real+1)(A6) ;default value <leave it always 1 for now>
|
||
|
||
SF pastDecimal(a6)
|
||
CLR.W saveCIndexR
|
||
MOVE.B D2,possible(A6,D1.W)
|
||
MOVE.W D2,sIndex(A6)
|
||
MOVE.W startLocs(myCanonicalR,D0.W),cIndexR
|
||
MOVE.W D2,rIndex(A6)
|
||
BRA.S @mergeMTest
|
||
@noNext:
|
||
CLR.B goingR
|
||
@mergeMTest:
|
||
compw Fsize(A6),cIndexR
|
||
SLE D0
|
||
MOVE.W sIndex(A6),D1
|
||
compw Ssize(A6),D1
|
||
SLE D1
|
||
AND.B D1,D0
|
||
AND.B D0,goingR
|
||
BRA @whileGoing
|
||
@doneGoing:
|
||
MOVE.B (FormCountR),D0
|
||
EXT.W D0
|
||
MOVE.B possible(A6,D0.W),D1 ;the eternal question: did we match?
|
||
|
||
BEQ.S @bestGuess ;no, so try free-form input
|
||
|
||
ADD.W D0,D0 ;yes, so see if we have a percentage to deal with
|
||
BTST #fIsPercent,flags(myCanonicalR,D0.W)
|
||
SNE D0
|
||
MOVE.B D0,doPercent(A6) ;and set the flag if we do
|
||
BRA @toReal ;go on to convert to real
|
||
|
||
|
||
@bestGuess:
|
||
;xxx<2/24/88:ldc>
|
||
; at this point we go back through the source and make a best guess
|
||
;FormatStr2X := bestGuess.
|
||
|
||
MOVE.W #fBestGuess, returnValue1(A6)
|
||
@freeForm
|
||
sf doPercent(a6) ; <9/22/88ldc>
|
||
sf isNeg(a6) ; <9/22/88ldc>
|
||
SF pastDecimal(a6) ; <9/20/88ldc>
|
||
ST checkFDmask(A6) ;any digit is OK now <05/22/89 pke>
|
||
|
||
MOVE.W #fPositive,(FormCountR) ;assume positive
|
||
MOVE.W #1,sIndex(A6) ;reset the vitals
|
||
MOVE.W #1,rIndex(A6)
|
||
|
||
@freeFormLoop:
|
||
@whileFF:
|
||
|
||
MOVE.W sIndex(A6),D0 ;have we run out of source?
|
||
compw Ssize(A6),D0
|
||
|
||
BGT @exitFreeForm
|
||
BSR @checkFD ; if it's not a digit, then just what is it
|
||
BNE @endFreeFormLoop ; was digit so loop to get the next char
|
||
|
||
|
||
CLR.W tempR ; not digit see which syntactical entity it matches
|
||
|
||
; loop through the parts table, index to each component in tempR
|
||
|
||
@pTabLoop:
|
||
ADDQ.W #1,tempR
|
||
compw #tokDecPoint,tempR ;if it's beyond decimal point, go to case
|
||
BGT.S @ffCase
|
||
MOVE.W tempR,D1 ;otherwise check against syntactical entry
|
||
ADD.W D1,D1
|
||
; added data offset <3/14/88ldc>
|
||
MOVE.W (-(tokLeftQuote*2)+data)(partsTableR,D1.W),D0
|
||
BSR @matchSS
|
||
BEQ.S @pTabLoop ;if there's no match then ignore it
|
||
@ffCase: ;jump table
|
||
MOVE.W tempR,D0
|
||
SUBQ.W #tokPercent,D0
|
||
BEQ.S @isPercent
|
||
SUBQ.W #(tokMinusSign-tokPercent),D0
|
||
BEQ.S @isMinus
|
||
SUBQ.W #(tokDecPoint-tokMinusSign),D0
|
||
BEQ.S @isDecPoint
|
||
SUBQ.W #1,D0 ; check fIsDecPoint-1
|
||
BEQ.S @isPastDecPoint
|
||
|
||
BRA @endFreeFormLoop ; ain't nothing
|
||
|
||
@isDecPoint:
|
||
; check for multiple decimals <9/20/88ldc>
|
||
tst.b pastDecimal(a6) ; have we already seen a decimal? <9/20/88ldc>
|
||
bne @setExtraDecimal ; yes, note error and exit <9/20/88ldc>
|
||
st pastDecimal(a6)
|
||
|
||
MOVE.W rIndex(A6),D0 ;tack on a decimal point
|
||
LEA real(A6),A0
|
||
MOVE.B #'.',0(A0,D0.W)
|
||
ADDQ.W #1,rIndex(A6)
|
||
|
||
|
||
BRA @endFreeFormLoop
|
||
@isMinus:
|
||
tst.b isNeg(a6) ; have we already seen a minus? <9/20/88ldc>
|
||
bne @setSpuriousChars ; yes, note error and exit <9/20/88ldc>
|
||
st isNeg(a6) ; else, just note that we have seen one
|
||
|
||
; Note that the convention used in the format scanner above is that negative is
|
||
; indicated if either isNeg is set (when '-' is seen in positive fmt) or formCount
|
||
; is fNegative;'-' is never added into the real number string. Change to use same
|
||
; convention here. <05/22/89 pke>
|
||
|
||
|
||
|
||
BRA.S @endFreeFormLoop
|
||
@isPercent:
|
||
tst.b doPercent(a6) ; only allow one percent symbol <9/22/88ldc>
|
||
|
||
IF forRom THEN
|
||
bne.s @setExtraPercent
|
||
ELSE
|
||
bne @setExtraPercent
|
||
ENDIF
|
||
|
||
st doPercent(A6)
|
||
BRA.S @endFreeFormLoop
|
||
@isPastDecPoint:
|
||
LEA PePlus(partsTableR),A0
|
||
BSR @expM ;check on E+
|
||
BNE.S @endFreeFormLoop ;it was E+
|
||
LEA PeMinusPlus(partsTableR),A0
|
||
JSR @expM ;check on E-
|
||
BNE.S @endFreeFormLoop ;it was E-
|
||
|
||
; <9/21/88ldc>flag spurious chars (e.g., "1x2") per bug #30677
|
||
; first compare it against the unquoted characters, may be two byte
|
||
|
||
clr.w -(a7) ; room for result
|
||
move.l source(a6), -(a7) ; source string and
|
||
move.w sIndex(a6), -(a7) ; source index
|
||
_CharByte ; for charbyte
|
||
movea.l source(a6), a0 ; get source
|
||
move.w sIndex(a6), d0 ; get index
|
||
adda.w d0, a0 ; current offset
|
||
move.b (a0)+, d0 ; get the first byte
|
||
tst.w (a7)+ ; one or two byte?
|
||
beq.s @singleByte ; one, so don't need to get next byte
|
||
lsl.w #8, d0 ; move into upper byte
|
||
move.b (a0)+, d0 ; lower byte of 2 byte char
|
||
@singleByte
|
||
LEA ((tokMaxSymbols-1)*2)(partsTableR),a0 ; unquoteds table in a0
|
||
MOVEQ #(tokEMinus-1),d1 ; loop counter
|
||
|
||
; <9/21/88ldc> loop through the unquoted characters in the number parts table
|
||
|
||
@unquotedLoop:
|
||
compw -(a0), d0 ; check against source table chars
|
||
dbeq d1, @unquotedLoop ; stop if we match
|
||
bne.s @setSpuriousChars ; this character not found in unquoted table
|
||
|
||
@bumpSourceString:
|
||
ADDQ.W #1,sIndex(A6) ;use CharByte to check for 2 byte char
|
||
|
||
|
||
CLR.W -(A7)
|
||
MOVE.L source(A6),D0
|
||
ADDQ #1,D0
|
||
MOVE.L D0,-(A7)
|
||
MOVE.W sIndex(A6),D0
|
||
;<1/23/88drs> Changed 1 line to fix bug
|
||
;Was subtracting 2 instead of 1
|
||
|
||
SUBQ.W #1,D0
|
||
MOVE.W D0,-(A7)
|
||
_CharByte
|
||
TST.W (A7)+
|
||
|
||
;<1/23/88drs> Changed 1 line to fix bug
|
||
;Was doing BLT.S instead of BGT.S
|
||
|
||
|
||
BGT.S @bumpSourceString ;get lower byte of two byte character
|
||
|
||
@endFreeFormLoop:
|
||
BRA @freeFormLoop
|
||
|
||
;<9/20/88ldc> flag errors
|
||
|
||
@emptyFormatString
|
||
MOVE.W #fEmptyFormatString, returnValue1(A6)
|
||
bra.s @toReal
|
||
|
||
@setExtraPercent
|
||
move.w #fExtraPercent, returnValue1(a6)
|
||
bra.s @toReal
|
||
|
||
@setExtraDecimal
|
||
move.w #fExtraDecimal, returnValue1(a6)
|
||
bra.s @toReal
|
||
|
||
@setSpuriousChars
|
||
move.w #fSpuriousChars, returnValue1(a6)
|
||
|
||
@toReal:
|
||
@exitFreeForm:
|
||
|
||
MOVE.W rIndex(A6),D0 ;set length of real# string
|
||
SUBQ.W #1,D0
|
||
BNE.S @rMerge
|
||
MOVEQ #1,D0 ;successfully matched literal string guaranteed to
|
||
;contain at least one digit: 1, -1, or 0
|
||
|
||
;<1/28/88drs> need check to see if we got anything useful from the source stirng at all
|
||
;<4/14/88ldc> added test for empty source
|
||
|
||
tst.w Ssize(A6) ;make sure we don't have an empty source string
|
||
beq.s @isNAN
|
||
|
||
;<3/31/88ldc> changed d0 to d1 to prevent trashing of #1 in d0
|
||
|
||
MOVE.B (FormCountR),D1 ;check if we had a match
|
||
EXT.W D1
|
||
TST.B possible(A6,D1.W) ;if no match and no digits, declare error
|
||
|
||
;<4/14/88ldc> changed branch target to @isNAN
|
||
BEQ.S @isNAN
|
||
; BNE.S @rMerge
|
||
; MOVE.W #fSpuriousChars, returnValue1(A6)
|
||
@rMerge:
|
||
MOVE.B D0, real(A6)
|
||
compb #fZero,(FormCountR) ;if formCount was zero then clear out x
|
||
BNE.S @isNonZero
|
||
MOVEA.L xOrig(A6),A0
|
||
CLR.L (A0)+
|
||
CLR.L (A0)+
|
||
CLR.W (A0)
|
||
BRA @zzMerge
|
||
|
||
;<4/14/88ldc> added @isNAN + 2 lines
|
||
|
||
@isNAN:
|
||
pea #'nan(17)'
|
||
bra.s @setupStr2Dec
|
||
|
||
@isNonZero:
|
||
;<4/14/88ldc> moved the following line to here from below
|
||
PEA real(A6) ; use the real string address
|
||
|
||
;<4/14/88ldc> added setupStr2Dec
|
||
|
||
@setupStr2Dec:
|
||
MOVE.W #1,indexF(A6) ; initial index into string
|
||
; PEA real(A6) ; use the real string address
|
||
PEA indexF(A6) ; index address
|
||
PEA decRecF(A6) ; decimal record address
|
||
PEA prefixF(A6) ; valid prefix address
|
||
FPSTR2DEC
|
||
|
||
; convert to extended
|
||
|
||
PEA decRecF(A6) ; decimal record address
|
||
MOVE.L xOrig(A6),-(SP) ; x address
|
||
FDEC2X
|
||
|
||
;<9/8/88ldc> use SANE to determine nan (cf bug #30678)
|
||
; result in d0
|
||
|
||
move.l xOrig(a6), a1
|
||
bsr GetSANEClass
|
||
cmp.w #posQNAN, d0
|
||
beq.s @returnNAN
|
||
cmp.w #negQNAN, d0
|
||
beq.s @returnNAN
|
||
cmp.w #posSNAN, d0
|
||
beq.s @returnNAN
|
||
cmp.w #negSNAN, d0
|
||
beq.s @returnNAN
|
||
cmp.w #posInf, d0
|
||
beq.s @returnOverflow
|
||
cmp.w #negInf, d0
|
||
beq.s @returnOverflow
|
||
|
||
|
||
MOVE.B doPercent(A6),D0 ;check if we need a percentage computation
|
||
BEQ.S @pMerge
|
||
PEA @hundredC
|
||
MOVE.L xOrig(A6),-(SP)
|
||
FDIVX ;divide by 100
|
||
@pMerge:
|
||
compb #fNegative,(FormCountR) ;if we picked up a negative somewhere…
|
||
BEQ.S @doNeg ;…then negate it
|
||
TST.B isNeg(A6) ;this is an informal negative
|
||
BEQ.S @zzMerge
|
||
@doNeg:
|
||
MOVEA.L xOrig(A6),A0
|
||
TST.L (A0)
|
||
BEQ.S @zzMerge ;don't negate a zero
|
||
EORI.B #$80,(A0)
|
||
bra.s @zzMerge
|
||
|
||
;<9/8/88ldc>
|
||
@returnNAN
|
||
MOVE.W #fFormStrIsNAN, returnValue1(A6) ; <9/8/88ldc>
|
||
bra.s @zzMerge
|
||
@returnOverflow
|
||
move.w #fFormatOverflow, returnValue1(a6) ; <9/8/88ldc>
|
||
|
||
@zzMerge:
|
||
MOVEM.L (A7)+,localRegs
|
||
move #argFrame1, d0 ; for StdUnlink
|
||
bra StdUnlink ; standard exit
|
||
|
||
|
||
CheckDebug 'FORMSTR2'
|
||
|
||
@hundredC:
|
||
DC.W $4005, $C800, $0000, $0000, $0000
|
||
|
||
ENDWITH
|
||
endp
|
||
|
||
maxStringLen EQU 50 ;internal strings
|
||
|
||
;------------------------------------------------------------
|
||
decForm record 0,increment
|
||
style ds.w 1 ; INTEGER
|
||
digits ds.w 1 ; INTEGER
|
||
ENDR
|
||
|
||
;------------------------------------------------------------
|
||
Decimal record 0,increment
|
||
sgn ds.w 1 ; 0..1
|
||
exp ds.w 1 ; INTEGER
|
||
sig ds.b 21 ; STRING[20]
|
||
ENDR
|
||
|
||
maxSANEsig EQU 20 ; max length of sig <05/22/89 pke>
|
||
;------------------------------------------------------------
|
||
FormX2StrFrame record {oldA61},decrement
|
||
returnValue1 ds.w 1 ; INTEGER
|
||
argFrameT1 EQU *
|
||
xOrig ds.l 1 ; VAR EXTENDED
|
||
myCanonical ds.l 1 ; VAR NumFormatString
|
||
partsTable ds.l 1 ; VAR NumberParts
|
||
out ds.l 1 ; VAR str255
|
||
selector1 ds.l 1
|
||
argFrame1 EQU argFrameT1-*
|
||
|
||
return1 ds.l 1
|
||
oldA61 ds.l 1
|
||
|
||
x ds.w 5 ; EXTENDED
|
||
formCount ds.b 1 ; FormatClass
|
||
negExp ds.b 1 ; BOOLEAN
|
||
doNegative ds.b 1 ; BOOLEAN
|
||
ALIGN 2
|
||
exp ds.b maxStringLen ; string
|
||
postDec ds.b maxStringLen ; string
|
||
preDec ds.b maxStringLen ; string
|
||
expFinal ds.b maxStringLen ; string
|
||
postDecFinal ds.b maxStringLen ; string
|
||
preDecFinal ds.b maxStringLen ; string
|
||
formStart ds.w 1 ; INTEGER
|
||
destPos ds.w 1 ; INTEGER
|
||
formPos ds.w 1 ; INTEGER
|
||
digCnt ds.w 1 ; INTEGER
|
||
;<3/30/88ldc> count the number of literal characters we have seen in the format string
|
||
litCnt ds.w 1 ; INTEGER
|
||
mantissa ds.b 1 ; BOOLEAN
|
||
oversized ds.b 1 ; BOOLEAN
|
||
res ds.w 1 ; INTEGER
|
||
expEnd ds.w 1 ; INTEGER
|
||
Nflags ds.w 1 ; BitPack
|
||
penLastLead ds.w 1 ; INTEGER
|
||
lastLead ds.w 1 ; INTEGER
|
||
startCut ds.w 1 ; INTEGER
|
||
lastSig ds.w 1 ; INTEGER
|
||
hold ds.w 1 ; INTEGER
|
||
ch ds.w 1 ; CHAR
|
||
while1 ds.w 1 ; INTEGER
|
||
tempInt ds.w 1 ; INTEGER <9/7/88ldc>
|
||
|
||
localFrame1 EQU *
|
||
|
||
ENDR
|
||
|
||
;------------------------------------------------------------
|
||
ConvertToStringFrame record {oldA62},decrement
|
||
argFrameT2 EQU *
|
||
xOrig ds.l 1 ; VAR EXTENDED
|
||
doExp ds.w 1 ; BOOLEAN
|
||
preDig ds.w 1 ; INTEGER
|
||
postDig ds.w 1 ; INTEGER
|
||
oldA6f2 ds.l 1
|
||
argFrame2 EQU argFrameT2-*
|
||
|
||
return2 ds.l 1
|
||
oldA62 ds.l 1
|
||
|
||
formatRecord ds decForm
|
||
y ds Decimal
|
||
j ds.w 1 ; INTEGER
|
||
i ds.w 1 ; INTEGER
|
||
localFrame2 EQU *
|
||
ENDR
|
||
|
||
;============================================================
|
||
; Num2Dec
|
||
;
|
||
; changes (whatever is changed by FX2DEC - could be a0-a1,d0-d2)
|
||
; calls FX2DEC (_FP68K)
|
||
;
|
||
Num2Dec proc
|
||
|
||
;============================================================
|
||
WITH FormX2StrFrame,ConvertToStringFrame
|
||
|
||
PEA formatRecord(A6)
|
||
MOVE.L xOrig(A6),-(SP)
|
||
PEA y(A6)
|
||
FX2DEC
|
||
RTS
|
||
|
||
ENDWITH
|
||
endp
|
||
|
||
;============================================================
|
||
; Int2String
|
||
;
|
||
; changes a0-a1,d0-d1
|
||
; uses/restores --
|
||
; calls --
|
||
;
|
||
Int2String proc
|
||
|
||
; Convert the postive integer in D0 to a string at a0
|
||
; i:= 1; str:= '0';
|
||
; WHILE D0 <> 0 DO BEGIN str[i]:= (x MOD 10) + '0'; x:= x DIV 10; END;
|
||
; str[0]:= i;
|
||
|
||
EXT.L D0
|
||
MOVE.L A0,A1
|
||
MOVE.B #1,(A0)+
|
||
MOVE.L A0,D1
|
||
@L1
|
||
DIVU #10,D0
|
||
SWAP D0
|
||
ADD.B #'0',D0
|
||
MOVE.B D0,(A0)+
|
||
SWAP D0
|
||
EXT.L D0
|
||
BNE.S @L1
|
||
SUB.L A0,D1
|
||
NEG.W D1
|
||
MOVE.B D1,(A1)
|
||
RTS
|
||
|
||
endp
|
||
|
||
;============================================================
|
||
; ConvertToString
|
||
;
|
||
; trashes a0-a1,d0-d1 (d2)
|
||
; uses/restores a2-a4,d4-d7
|
||
; calls Num2Dec (may change a0-a1,d0-d2)
|
||
; Int2String changes a0-a1,d0-d1
|
||
;
|
||
ConvertToString proc
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
localRegs reg D4-D7/A2-A4
|
||
|
||
postDigR EQU d6 ; number of digits after dec point
|
||
preDigR EQU d4 ; number of digits before dec pt
|
||
ff EQU a4 ; old a6 value FormX2StrFrame
|
||
yExpR EQU a2
|
||
|
||
fixedDecimal EQU 1
|
||
|
||
;============================================================
|
||
WITH FormX2StrFrame,ConvertToStringFrame
|
||
|
||
LINK A6,#localFrame2
|
||
MOVEM.L localRegs,-(A7)
|
||
MOVE.W postDig(A6),postDigR ;load up the registers
|
||
MOVE.W preDig(A6),preDigR
|
||
MOVEA.L oldA6f2(A6),ff
|
||
MOVE.B postDigR,postDec(ff) ;initialize the preDec,postDec string lengths
|
||
MOVE.B preDigR,preDec(ff)
|
||
MOVE.W postDigR,lastSig(ff) ;lastSig is the position of the last significant digit
|
||
MOVE.B doExp(A6),D0 ;check for exponent
|
||
BEQ @noExp ;…no exponent
|
||
|
||
LEA y.exp(A6),yExpR ;this is frequently enough used to warrant a register
|
||
CLR.B formatRecord.style(A6) ;= floatDecimal style
|
||
MOVE.W preDigR,D0 ;total digits is simply pre & post decimal counts
|
||
ADD.W postDigR,D0
|
||
MOVE.W D0,formatRecord.digits(A6)
|
||
JSR Num2Dec ;convert x to decimal string
|
||
|
||
; for 0, exp is undefined and sig = '0' (i.e., only one digit char). (See Apple
|
||
; Numerics Manual, 2nd ed., p. 28). So, the normal code for adjusting exp and
|
||
; setting the preDec and postDec strings doesn't work (BRC #39590)
|
||
CMPI.B #'0',y.sig+1(A6) ;DecRec=0 if sig[1]='0' (Numerics Manual p.28)
|
||
BNE.S @fixForZeroDone ;if DecRec=0, set exp, preDec, postDec appropriately
|
||
MOVE.B #'0',D0 ;we'll be setting preDec/postDec with '0'
|
||
LEA (preDec+1)(ff),A0 ;address of preDec string…
|
||
MOVE.W preDigR,D7 ;D7 is the number of digits to transfer
|
||
SUBQ.W #1,D7 ;
|
||
BLT.S @fixForZeroPreDone ;
|
||
@fixForZeroPre: ;
|
||
MOVE.B D0,(A0)+ ;put correct # of '0's into preDec string
|
||
DBRA D7,@fixForZeroPre ;
|
||
@fixForZeroPreDone: ;
|
||
LEA (postDec+1)(ff),A0 ;address of preDec string…
|
||
MOVE.W postDigR,D7 ;D7 is the number of digits to transfer
|
||
SUBQ.W #1,D7 ;courtesy DBRA
|
||
BLT.S @fixForZeroPostDone ;the zero case
|
||
@fixForZeroPost: ;
|
||
MOVE.B D0,(A0)+ ;put correct # of '0's into postDec string
|
||
DBRA D7,@fixForZeroPost ;
|
||
@fixForZeroPostDone: ;
|
||
CLR.W (yExpR) ;now set exp to 0
|
||
CLR.B negExp(ff) ;indicate not a negative exp
|
||
BRA.S @pastPostDec ;
|
||
@fixForZeroDone: ;
|
||
|
||
MOVEQ #0,D1 ;default: no negative exponent
|
||
MOVE.W (yExpR),D0 ;check if the exponent will be negative
|
||
ADD.W postDigR,D0 ;yExp:= yExp + postDig
|
||
BPL.S @noNegate ;negExp:= yExp + postDig < 0
|
||
NEG.W D0 ;yExp:= ABS(yExp);
|
||
ST D1 ;negExp:= TRUE
|
||
@noNegate:
|
||
MOVE.B D1,negExp(ff) ;set the flag
|
||
MOVE.W D0,(yExpR) ;give yExpR its final value
|
||
LEA (preDec+1)(ff),A0 ;load preDec with the digits from y's significand,
|
||
LEA y.Sig+1(A6,preDigR.W),A1 ;…but do it in reverse order:A1 is the decimal point position
|
||
MOVE.L A1,A3 ;A3 will be our local counter
|
||
MOVE.W preDigR,D7 ;D7 is the number of digits to transfer
|
||
SUBQ.W #1,D7 ;courtesy DBRA
|
||
BLT.S @preDecDone ;the zero case
|
||
@preDecLoop:
|
||
MOVE.B -(A3),(A0)+ ;load 'em up
|
||
DBRA D7,@preDecLoop
|
||
@preDecDone:
|
||
LEA (postDec+1)(ff),A0 ;now do the same for postDec
|
||
MOVE.W postDigR,D7 ;again D7 is the number of digits to transfer
|
||
SUBQ.W #1,D7
|
||
BLT.S @pastPostDec
|
||
@postDecLoop:
|
||
MOVE.B (A1)+,(A0)+ ;this time, don't reverse the order
|
||
DBRA D7,@postDecLoop
|
||
@pastPostDec:
|
||
MOVE.W (yExpR),D0 ;now convert the exponent to an integer string
|
||
LEA exp(ff),A0
|
||
JSR Int2String
|
||
BRA.S @donePreDec
|
||
@noExp:
|
||
SF negExp(ff) ;when there's no exponent, I guess it's not negative
|
||
CLR.B exp(ff) ;needs some size
|
||
MOVE.B #fixedDecimal,formatRecord.style(A6) ;set up style and digit count
|
||
MOVE.W postDigR,formatRecord.digits(A6) ;fixed style only wants to know…
|
||
;Num2Dec(formatRecord, x, y);
|
||
;result is in y(A6)
|
||
JSR Num2Dec ;…how many digits after the decimal point
|
||
LEA (postDec+1)(ff),A0 ;@postDec[1]
|
||
CLR.W D0
|
||
; j := ORD(y.sig[0])-postDig+1;
|
||
LEA y.sig(A6),A3 ;we may not have enough digits to fill the request,
|
||
MOVE.B (A3)+,D0 ;and here's how we find out.
|
||
MOVE.W postDigR,D7 ;first see how many is requested
|
||
SUBQ.W #1,D7 ;if none, then…
|
||
BLT.S @donePost ;…fine, forget it
|
||
SUB.W postDigR,D0 ;then see if Num2Dec met the request
|
||
BGE.S @canCopy ;yes, it did
|
||
|
||
;FOR i := 1 to postDig DO BEGIN
|
||
; IF j <= 0 THEN BEGIN
|
||
; postDec[i] := '0';
|
||
; postDig := postDig - 1;
|
||
; END ELSE BEGIN
|
||
; postDec[i] := y.sig[j];
|
||
; END;
|
||
; j := j+1;
|
||
;END
|
||
|
||
@makeZeroes: ;no, so fill with zeroes
|
||
|
||
MOVE.B #'0',(A0)+
|
||
SUBQ.W #1,postDigR ;these zeroes weren't originally taken into account…
|
||
ADDQ.W #1,D0 ;…when making preDig computation so we have to dec postDig
|
||
DBGE D7,@makeZeroes ;fill until D0 has made up the deficit
|
||
|
||
SUBQ.W #1,D7 ;decrement because the DBGE didn't the last time
|
||
@canCopy: ;and go for the real digits
|
||
ADDA.W D0,A3 ;this is the position into the decimal string
|
||
@copyPost:
|
||
MOVE.B (A3)+,(A0)+
|
||
DBRA D7,@copyPost
|
||
|
||
;IF preDig <> 0 THEN BEGIN
|
||
; j := ORD (y.sig[0])-postDig;
|
||
; preDec[0] := CHR[j];
|
||
; FOR i := 1 TO j DO
|
||
; preDec[i] := y.sig[j-i+1];
|
||
;END;
|
||
|
||
@donePost:
|
||
;; TST.W preDigR ;now check if we need pre-decimal digits <2/25/88med/ldc>
|
||
;; BEQ.S @donePreDec ;not today <2/25/88med/ldc>
|
||
LEA y.sig(A6),A3 ;put A3 to work
|
||
MOVEQ #0,D5 ;clear out D5
|
||
MOVE.B (A3)+,D5 ;and find out how many digits in significand
|
||
SUB.W postDigR,D5 ;postDigR reflects how many we've used up
|
||
ADDA.W D5,A3 ;move A3 beyond that point to copy backwards
|
||
LEA preDec(ff),A0 ;A0 was idle also
|
||
MOVE.B D5,(A0)+ ;so give it a length
|
||
SUBQ.W #1,D5 ;and accommodate DBRA
|
||
BLT.S @noPreDec
|
||
@preDecLoop1:
|
||
MOVE.B -(A3),(A0)+ ;copy reverse
|
||
DBRA D5,@preDecLoop1
|
||
|
||
;IF postDec[lastSig] = '0' THEN BEGIN
|
||
; REPEAT
|
||
; lastSig := lastSig-1;
|
||
; UNTIL (lastSig = 1) OR (postDec[lastSig] <> '0');
|
||
;END
|
||
|
||
@noPreDec:
|
||
@donePreDec:
|
||
MOVE.W lastSig(ff),D0 ;now knock off trailing zeroes we don't need
|
||
SUB.W #((-postDec)-1),D0 ;find the end of the postDec string we made
|
||
LEA (ff,D0.W),A0 ;and point A0 past it for predecrement
|
||
|
||
@eatZeroes:
|
||
CMP.B #'0',-(A0) ;is it a trailing zero?
|
||
BNE.S @LOUT ;no; we're done
|
||
;<2/25/88drs> Added two lines because we need to preserve one zero beyond the decimal point.
|
||
CMP.W #1,lastSig(ff)
|
||
BEQ.S @LOUT
|
||
SUBQ.W #1,lastSig(ff) ;otherwise, eat it and smile
|
||
;<2/25/88drs> Changed this line to branch always instead of checking for zero. The check is now for one
|
||
BRA.S @eatZeroes ;someday we have to run out of digits
|
||
|
||
@LOUT:
|
||
MOVEM.L (A7)+,localRegs
|
||
|
||
move #argFrame2, d0 ; for StdUnlink
|
||
bra StdUnlink ; standard exit
|
||
|
||
CheckDebug 'CONVERTT'
|
||
ENDWITH
|
||
endp
|
||
|
||
;------------------------------------------------------------
|
||
AppendSymbolFrame record {oldA62},decrement
|
||
argFrameT2 EQU *
|
||
c ds.w 1 ; CHAR
|
||
source ds.l 1 ; VAR str255
|
||
dest ds.l 1 ; VAR str255
|
||
DoSendChar ds.l 2 ; FUNCTION(x:WideChar;VAR y:str255;VAR z:INTEGER):INTEGER
|
||
oldA6f2 ds.l 1
|
||
argFrame2 EQU argFrameT2-*
|
||
|
||
return2 ds.l 1
|
||
oldA62 ds.l 1
|
||
|
||
res ds.w 1 ; INTEGER
|
||
holdMyCanonical ds.l 1
|
||
localFrame2 EQU *
|
||
ENDR
|
||
|
||
;============================================================
|
||
; ExpHandling
|
||
;
|
||
; trashes a0,d0 (a1, d1-d2)
|
||
; uses/restores a2-a4,d5-d7
|
||
; calls SendChar here trashes a0-a1,d0-d2
|
||
;
|
||
ExpHandling proc
|
||
|
||
;------------------------------------------------------------
|
||
ExpHandlingFrame record {oldA63},decrement
|
||
argFrameT3 EQU *
|
||
plusData ds.l 1 ; VAR WideCharArr
|
||
oldA6f3 ds.l 1
|
||
argFrame3 EQU argFrameT3-*
|
||
|
||
return3 ds.l 1
|
||
oldA63 ds.l 1
|
||
|
||
i ds.w 1 ; INTEGER
|
||
k ds.w 1 ; INTEGER
|
||
temp ds.l 1 ; ^WideCharArr
|
||
localFrame3 EQU *
|
||
ENDR
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
localRegs reg D5-D7/A2-A4
|
||
af EQU a2
|
||
ff EQU a4
|
||
destR EQU a2
|
||
partsTableR EQU a0
|
||
plusDataR EQU a3
|
||
|
||
;============================================================
|
||
WITH ExpHandlingFrame, AppendSymbolFrame, FormX2StrFrame,FormatStringPriv, NumberParts
|
||
|
||
LINK A6,#localFrame3
|
||
MOVEM.L localRegs,-(A7)
|
||
MOVEA.L oldA6f3(A6),af ;AppendSymbol frame
|
||
MOVEA.L oldA6f2(af),ff ;FormatX2Str frame
|
||
MOVE.L dest(af),destR ;load up a few lazy registers
|
||
MOVEA.L partsTable(ff),partsTableR
|
||
SF mantissa(ff) ;mantissa flag says we're into the exponent
|
||
MOVE.B negExp(ff),D0 ;if negExp, then we know we need E-
|
||
BEQ.S @needEPlus
|
||
LEA PeMinus(partsTableR),A3 ;grab the E- format
|
||
BRA.S @EMerge ;and continue
|
||
@needEPlus:
|
||
MOVEA.L plusData(A6),plusDataR ;otherwise retrieve E+ or E, whichever came
|
||
@EMerge:
|
||
MOVE.W WideCharArr.size(plusDataR),D5 ;set up D5 as loop end
|
||
CLR.W D7 ;and D7 as loop counter
|
||
BRA.S @loopTest ;start loop
|
||
@loopStart: ;loop for sending exponent characters to output stream
|
||
CLR.W -(A7) ;result
|
||
MOVE.W D7,D0
|
||
ADD.W D0,D0
|
||
MOVE.W WideCharArr.data(plusDataR,D0.W),-(A7) ;the character itself
|
||
MOVE.L destR,-(A7) ;what string the character is going to
|
||
PEA destPos(ff) ;and how far into the string
|
||
JSR SendChar
|
||
MOVE.W (A7)+,D6 ;just ignore the result. Apathy, I guess.
|
||
ADDQ.W #1,D7 ;loop counter increment
|
||
@loopTest:
|
||
compw D5,D7 ;done yet?
|
||
BLE.S @loopStart
|
||
@L168:
|
||
MOVEM.L (A7)+,localRegs
|
||
|
||
move.w #argFrame3, d0 ; for StdUnlink
|
||
bra StdUnlink ; standard exit
|
||
|
||
|
||
CheckDebug 'EXPHANDL'
|
||
ENDWITH
|
||
endp
|
||
|
||
|
||
;============================================================
|
||
; AppendSymbol
|
||
;
|
||
; trashes a0-a1,d0-d1
|
||
; uses/restores a3-a4,d4-d7
|
||
; calls ExpHandling trashes a0,d0 (a1,d1-d2)
|
||
; ? some procedure with a handle at DoSendChar(A6) + 2 - trashes ?
|
||
;
|
||
AppendSymbol proc
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
|
||
localRegs reg D5-D7/A2-A4 ; why was a2 added? -pke, 02/21/89
|
||
|
||
cR EQU d6
|
||
sourceR EQU d5
|
||
ff EQU a4
|
||
resR EQU d7
|
||
partsTableR EQU a3
|
||
|
||
;============================================================
|
||
WITH AppendSymbolFrame, FormX2StrFrame,FormatStringPriv, NumberParts, SMgrRecord
|
||
|
||
LINK A6,#localFrame2
|
||
MOVEM.L localRegs,-(A7)
|
||
MOVE.W c(A6),cR ;load up some registers
|
||
MOVE.L source(A6),sourceR
|
||
MOVEA.L oldA6f2(A6),ff ;FormatX2Str frame
|
||
|
||
;xxx <2/23/88:ldc> replaced #1 with #fFormatOK
|
||
MOVEQ #fFormatOK, resR ;register storage for return value
|
||
MOVE.L myCanonical(ff),holdMyCanonical(A6)
|
||
MOVEA.L partsTable(ff),partsTableR
|
||
compw #32,cR ;printable character?
|
||
BLT.S @doFormByte ;no. It's a format byte
|
||
MOVEA.L dest(A6),A0 ;yes, it's printable; copy it verbatim
|
||
MOVE.W destPos(ff),D0 ;dest[destPos]:= c
|
||
MOVE.B cR,0(A0,D0.W)
|
||
ADDQ.W #1,destPos(ff) ;and don't forget to increment destPos
|
||
;<3/30/88ldc> track the number of literal chars in format string
|
||
ADDQ.W #1,litCnt(ff)
|
||
BRA @almostDone
|
||
@doFormByte:
|
||
MOVE.W cR,D0 ;CASE ORD(c):jump table computations
|
||
SUBQ.W #tokLeader,D0 ;tokLeader is lowest entry in the table
|
||
BMI @outOfRange
|
||
compw #(tokEMinus-tokLeader),D0 ;tokEMinus is highest entry
|
||
BGT @outOfRange
|
||
ADD.W D0,D0 ;these are word offsets of course
|
||
MOVE.W @jTab(D0.W),D0
|
||
JMP *+2(D0.W)
|
||
@jTab:
|
||
DC.W @leads-@jTab+2, @leads-@jTab+2, @leads-@jTab+2
|
||
DC.W @noEntry-@jTab+2, @others-@jTab+2, @others-@jTab+2
|
||
DC.W @others-@jTab+2, @noEntry-@jTab+2, @noEntry-@jTab+2
|
||
DC.W @noEntry-@jTab+2, @noEntry-@jTab+2, @ePlus-@jTab+2
|
||
DC.W @eMinus-@jTab+2
|
||
|
||
@ePlus:
|
||
PEA PePlus(partsTableR) ;create the exponent with PePlus
|
||
MOVE.L A6,-(A7)
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
GetSMgrCore a0 ; intlSpec for vector
|
||
move.l sVectExpHandling(a0), a0 ; <6/21/88ldc>
|
||
jsr (a0) ; call vector <6/17/88ldc>
|
||
|
||
ELSE
|
||
|
||
JSR ExpHandling
|
||
|
||
ENDIF
|
||
|
||
BRA @almostDone
|
||
|
||
@eMinus:
|
||
PEA PeMinusPlus(partsTableR) ;create the exponent with PeMinusPlus
|
||
MOVE.L A6,-(A7)
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
GetSMgrCore a0 ; intlSpec for vector
|
||
move.l sVectExpHandling(a0), a0 ; <6/21/88ldc>
|
||
jsr (a0) ; call vector <6/17/88ldc>
|
||
|
||
ELSE
|
||
|
||
JSR ExpHandling
|
||
|
||
ENDIF
|
||
|
||
BRA @almostDone
|
||
|
||
@leads: ;This gets complicated.
|
||
MOVEA.L sourceR,A0 ;first find out if we have any digits left
|
||
CLR.W D0
|
||
MOVE.B (A0),D0
|
||
compw digCnt(ff),D0
|
||
BLT.S @noDigsLeft
|
||
LEA Nflags(ff),A1 ;yes, so decide whether to send a Roman digit or other
|
||
BTST #fIsAltNum,(A1)
|
||
BEQ.S @isRoman
|
||
CLR.W -(A7) ;result space for DoSendChar
|
||
MOVE.W digCnt(ff),D0 ;get the roman digit into D1
|
||
CLR.W D1
|
||
MOVE.B 0(A0,D0.W),D1
|
||
SUB.W #'0',D1 ;now subtract '0' to get an index
|
||
ADD.W D1,D1 ;word index, that is
|
||
LEA (altNumTable.data)(partsTableR),A0 ;altNumTable address
|
||
MOVE.W 0(A0,D1.W),-(A7) ;push the foreign digit
|
||
MOVE.L dest(A6),-(A7) ;and the destination address
|
||
PEA destPos(ff) ;and the destination position
|
||
LEA DoSendChar(A6),A0 ;go through the cranky procedure variable computations
|
||
MOVE.L (A0)+,D0
|
||
BEQ.S @L181
|
||
MOVE.L D0,-(A7)
|
||
@L181:
|
||
MOVEA.L (A0),A0
|
||
JSR (A0) ;and finally ship off the character
|
||
MOVE.W (A7)+,resR
|
||
BRA.S @mergeHadLead
|
||
@isRoman:
|
||
MOVEA.L dest(A6),A0 ;roman digits are roman digits; just copy them
|
||
MOVE.W destPos(ff),D0
|
||
MOVEA.L sourceR,A1
|
||
MOVE.W digCnt(ff),D1
|
||
MOVE.B 0(A1,D1.W),0(A0,D0.W)
|
||
ADDQ.W #1,destPos(ff) ;and increment the destination pointer
|
||
@mergeHadLead:
|
||
ADDQ.W #1,digCnt(ff) ;since we've tacked on another digit, up digCnt also
|
||
MOVE.W destPos(ff),lastLead(ff) ;this little obscurity is bookkeeping for the…
|
||
;…possibility that we may have to backtrack because of optional digits
|
||
BRA.S @mergeLead ;basically, let's get out of here
|
||
|
||
@noDigsLeft:
|
||
compw #tokNonLeader,cR ;find out if this is a nonLeader or not
|
||
BNE.S @notNonLeader
|
||
MOVE.W destPos(ff),penLastLead(ff) ;if it is, then save the position because…
|
||
;…we may need to clip back to it because of optional characters
|
||
BRA.S @mergeLead ;and stay out!
|
||
|
||
;<3/25/88ldc> added common call to DoSendChar to clean up code
|
||
@DoDoSendChar:
|
||
MOVE.W cR,D0
|
||
ADD.W D0,D0
|
||
CLR.W -(A7)
|
||
MOVE.W -(tokLeftQuote*2)+data(partsTableR,D0.W),-(A7)
|
||
MOVE.L dest(A6),-(A7)
|
||
PEA destPos(ff)
|
||
LEA DoSendChar(A6),A0
|
||
MOVE.L (A0)+,D0
|
||
BEQ.S @skipIt
|
||
MOVE.L D0,-(A7)
|
||
@skipIt:
|
||
MOVEA.L (A0),A0
|
||
JSR (A0)
|
||
MOVE.W (A7)+,resR
|
||
RTS
|
||
|
||
@notNonLeader
|
||
;<3/25/88ldc> made proc call to reduce code size
|
||
JSR @DoDoSendChar ;res:= DoSendChar(data[ORD(c)],dest,destPos);
|
||
;<3/25/88ldc> added this line to fix problem of stripping off of leaders
|
||
MOVE.W destPos(ff),lastLead(ff)
|
||
CLR.W penLastLead(ff) ;reset penultimate LastLead because only junk between…
|
||
;…nonLeaders is optional
|
||
BRA.s @mergeLead
|
||
|
||
@others:
|
||
;<3/25/88ldc> changed to proc call
|
||
JSR @DoDoSendChar ;res:= DoSendChar(data[ORD(c)],dest,destPos);
|
||
|
||
@mergeLead:
|
||
@almostDone:
|
||
@outOfRange:
|
||
@noEntry:
|
||
compw #fFormatOK,resR ;has resR been modified?
|
||
BEQ.S @noResChange
|
||
MOVEA.L oldA6f2(A6),A0 ;update the function result if it has
|
||
MOVE.W resR, returnValue1(A0)
|
||
@noResChange:
|
||
MOVEM.L (A7)+,localRegs
|
||
|
||
move #argFrame2, d0 ; for StdUnlink
|
||
bra StdUnlink ; standard exit
|
||
|
||
CheckDebug 'APPENDSY'
|
||
ENDWITH
|
||
endp
|
||
|
||
;============================================================
|
||
; xFormX2Str
|
||
;
|
||
; trashes a0-a1,d0-d1
|
||
; uses/restores a2-a5,d4-d7
|
||
; calls ConvertToString here trashes a0-a1,d0-d1 (d2?)
|
||
; SendCharRev here trashes a0-a1,d0-d2
|
||
; AppendSymbol here trashes a0-a1,d0-d2 + ?
|
||
; NextFormatClass here changes d0
|
||
; SendChar here trashes a0-a1,d0-d2
|
||
;
|
||
xFormX2Str proc
|
||
|
||
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
localRegs reg D4-D7/A2-A5
|
||
|
||
destPosR EQU a5
|
||
resR EQU d5
|
||
myCanonicalR EQU a4
|
||
partsTableR EQU a3
|
||
oversizedR EQU d4
|
||
formCountR EQU d6
|
||
NflagsR EQU a2
|
||
formPosR EQU d7
|
||
;============================================================
|
||
WITH FormX2StrFrame,FormatStringPriv, NumberParts, SMgrRecord
|
||
|
||
LINK A6,#localFrame1
|
||
MOVEM.L localRegs,-(A7)
|
||
MOVEA.L xOrig(A6),A0
|
||
LEA destPos(A6),destPosR
|
||
LEA x(A6),A1
|
||
MOVE.L A1,A2
|
||
MOVE.L (A0)+,(A2)+ ;need a local copy because it might change
|
||
MOVE.L (A0)+,(A2)+
|
||
MOVE.W (A0),(A2)
|
||
;xxx<2/23/88:ldc> replaced #1 with symbolic constant #fFormatOK
|
||
MOVEQ #fFormatOK,resR ;the original idea was to update returnValue1…
|
||
;…if resR was ever modified. I'm not through yet
|
||
MOVE.W #fFormatOK, returnValue1(A6)
|
||
MOVEA.L myCanonical(A6),myCanonicalR ;make use of the hired hands
|
||
|
||
tst.b formString(myCanonicalR) ; check for empty format string <9/7/88ldc>
|
||
beq @emptyFormatString
|
||
|
||
MOVEA.L partsTable(A6),partsTableR
|
||
SF oversizedR ;initialize the hell out of everything
|
||
ST mantissa(A6)
|
||
SF doNegative(A6)
|
||
MOVE.W #(maxStringLen-1),D0
|
||
MOVE.B D0,preDecFinal(A6)
|
||
MOVE.B D0,postDecFinal(A6)
|
||
MOVE.B D0,expFinal(A6)
|
||
|
||
;<9/7/88ldc> test for minus zero, overflow or NAN cf bug # 30675, 33761
|
||
bsr GetSaneClass ; get the class of xOrig
|
||
cmp.w #negZero, d0 ; negative zero?
|
||
beq.s @isZero ; yes
|
||
cmp.w #posQNAN, d0
|
||
beq @returnNAN
|
||
cmp.w #negQNAN, d0
|
||
beq @returnNAN
|
||
cmp.w #posSNAN, d0
|
||
beq @returnNAN
|
||
cmp.w #negSNAN, d0
|
||
beq @returnNAN
|
||
cmp.w #posInf, d0
|
||
beq @returnOverflow
|
||
cmp.w #negInf, d0
|
||
beq @returnOverflow
|
||
|
||
; if positive format is not valid, give up <05/22/89 pke>
|
||
BTST.B #fExists,(flags+2*fPositive)(myCanonicalR)
|
||
BEQ @emptyFormatString
|
||
|
||
TST.B (A1) ;xOrig > 0?
|
||
BPL.S @noNeg
|
||
|
||
MOVEQ #fNegative,formCountR
|
||
EORI.B #$80,(A1) ;flip top order bit to negate
|
||
BRA.S @endXTest
|
||
|
||
;NOTE: don't modify A1 until @donePercent!!
|
||
|
||
@noNeg:
|
||
BNE.S @isPos ;is it negative?
|
||
|
||
@isZero
|
||
|
||
MOVEQ #fZero,formCountR
|
||
BRA.S @endXTest
|
||
@isPos:
|
||
MOVEQ #fPositive,formCountR ;it is positive
|
||
@endXTest:
|
||
MOVE.W formCountR,D0 ;Do we have a format corresponding to x?
|
||
ADD.W D0,D0
|
||
BTST #fExists,flags(myCanonicalR,D0.W)
|
||
BNE.S @doneFormat
|
||
compb #fNegative,formCountR ;is x negative?
|
||
SEQ doNegative(A6) ;let everyone know; in any case, positive is default
|
||
MOVEQ #fPositive,formCountR
|
||
@doneFormat:
|
||
MOVE.W formCountR,D0 ;now make sure the format doesn't specify percents
|
||
ADD.W D0,D0
|
||
LEA Nflags(A6),NflagsR
|
||
LEA flags(myCanonicalR,D0.W),A0
|
||
MOVE.W (A0),(NflagsR)
|
||
BTST #fIsPercent,(NflagsR)
|
||
BEQ.S @donePercent
|
||
PEA @c100 ;its a constant 100 to multiply by
|
||
MOVE.L A1,-(A7)
|
||
FMULX
|
||
@donePercent:
|
||
PEA x(A6) ;set up params for ConvertToString
|
||
MOVEQ #0,D0 ;determine if either EMinus or EPlus is applicable
|
||
MOVE.W (NflagsR),D0
|
||
AND.L #fEMEP,D0
|
||
SNE D0
|
||
MOVE.B D0,-(A7)
|
||
MOVE.W formCountR,D0 ;push preDig[formCount] and postDig[formCount]
|
||
ADD.W D0,D0
|
||
MOVE.W PreDig(myCanonicalR,D0.W),-(A7)
|
||
MOVE.W PostDig(myCanonicalR,D0.W),-(A7)
|
||
MOVE.L A6,-(A7)
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
GetSMgrCore a0 ; set up vectorized ConvertToString
|
||
move.l sVectConvertToString(a0), a0
|
||
jsr (a0) ; call vector <6/17/88ldc>
|
||
|
||
ELSE
|
||
|
||
JSR ConvertToString ;and finally convert x to a string
|
||
|
||
ENDIF
|
||
|
||
MOVE.W #1,(destPosR) ;initialize all these silly indices
|
||
MOVE.W #1,digCnt(A6)
|
||
; initialize the number of literal chars <3/30/88ldc>
|
||
MOVE.W #1, litCnt(a6)
|
||
MOVE.W formCountR,D0 ;formPosR:= decLocs[formCount]-1
|
||
ADD.W D0,D0
|
||
MOVE.W decLocs(myCanonicalR,D0.W),formPosR
|
||
SUBQ.W #1,formPosR
|
||
CMP.B #fPositive,formCountR ;set formStart. If formCount is positive, formStart is just 1
|
||
BNE.S @notPositive
|
||
MOVE.W #1,formStart(A6)
|
||
BRA.S @mergeFormStart
|
||
@notPositive: ;otherwise, it's startLocs[formCount]
|
||
MOVE.W startLocs(myCanonicalR,D0.W),formStart(A6)
|
||
@mergeFormStart:
|
||
BTST #fIsDecimal,(NflagsR) ;do we have a decimal point to worry about?
|
||
BEQ.S @endDecPoint
|
||
CLR.W -(A7) ;go ahead a start preDecFinal with a decimal point
|
||
MOVE.W data+((tokDecPoint-tokLeftQuote)*2)(partsTableR),-(A7)
|
||
PEA preDecFinal(A6) ;(because preDecFinal is a reversed string)
|
||
MOVE.L destPosR,-(A7) ;push the position within preDecFinal
|
||
JSR SendCharRev ;the reversed version of sendChar
|
||
MOVE.W (A7)+,resR ;accumulate result
|
||
@endDecPoint:
|
||
CLR.W penLastLead(A6) ;so far, no nonLeaders that can bracket optional material
|
||
|
||
;<1/23/88drs> Changed 1 line to fix bug.
|
||
;destPos, rather than 0, must be moved into lastLead to handle numbers
|
||
;less than 1 with only nonLeaders to the left of the decimal point.
|
||
|
||
MOVE.W (destPosR),lastLead(A6)
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
move.l NFlagsR, -(sp) ; save this little mother <6/17/88ldc>
|
||
GetSMgrCore NflagsR ; get this for jump to AppendSymbol <6/17/88ldc>
|
||
move.l sVectAppendSymbol(NflagsR), NflagsR
|
||
|
||
ENDIF
|
||
|
||
@preDecLoop:
|
||
compw formStart(A6),formPosR ;WHILE formPosR >= formStart
|
||
BLT.S @endPreDecLoop
|
||
CLR.W D1
|
||
MOVE.B formString(myCanonicalR,formPosR.W),D1
|
||
MOVE.W D1,-(A7) ;push current format code
|
||
PEA preDec(A6) ;push source
|
||
PEA preDecFinal(A6) ;push destination
|
||
PEA SendCharRev ;push SendCharRev procedure
|
||
CLR.L -(A7)
|
||
MOVE.L A6,-(A7) ;and the silly frame pointer
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
jsr (NflagsR) ; get from intlSpec <6/17/88ldc>
|
||
|
||
ELSE
|
||
|
||
JSR AppendSymbol ; vectorized <6/17/88ldc>
|
||
|
||
ENDIF
|
||
|
||
TST.W penLastLead(A6) ;if bracketed by nonLeaders, cut out the optional material
|
||
BEQ.S @mergePenTest
|
||
MOVE.W lastLead(A6),(destPosR) ;snip it off by moving destPos back
|
||
CLR.W penLastLead(A6) ;and reset penLastLead
|
||
@mergePenTest:
|
||
SUBQ.W #1,formPosR ;in any case, decrement the form index
|
||
BRA.S @preDecLoop
|
||
|
||
@endPreDecLoop:
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
move.l (sp)+, NflagsR ; restore the saved register <6/17/88ldc>
|
||
|
||
ENDIF
|
||
|
||
CLR.W D0
|
||
MOVE.B preDec(A6),D0 ;check if our digit count <= the available digits
|
||
compw digCnt(A6),D0
|
||
BLT.S @mergeDigCheck
|
||
|
||
; destPos = litCnt means we have exactly matched the literal chars <3/30/88ldc>
|
||
; in the format string, hence no overflow
|
||
|
||
move.w destPos(a6), d0
|
||
compw litCnt(a6), d0
|
||
beq.s @mergeDigCheck
|
||
ST oversizedR ;we're a wreck
|
||
MOVE.W #fFormatOverflow,returnValue1(A6)
|
||
@mergeDigCheck:
|
||
MOVE.W (destPosR),D0 ;now set the size of preDecFinal
|
||
SUBQ.W #1,D0
|
||
MOVE.B D0,preDecFinal(A6)
|
||
MOVE.B oversizedR,D0 ;did we overflow our available number size?
|
||
BNE @mergePreDecV
|
||
MOVE.B formCountR,D0 ;find the location of the decimal point in form string
|
||
EXT.W D0
|
||
ADD.W D0,D0
|
||
MOVE.W decLocs(myCanonicalR,D0.W),formPosR ;set formPos to that location
|
||
BTST #fIsDecimal,(NflagsR) ;if we had a decimal point then increment our position
|
||
BEQ.S @mergeDecPoint
|
||
ADDQ.W #1,formPosR
|
||
@mergeDecPoint:
|
||
MOVE.W #1,(destPosR) ;again go crazy initializing things
|
||
MOVE.W #1,digCnt(A6)
|
||
CLR.W startCut(A6) ;startCut tells where to chop off trailing zeroes
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
move.l NFlagsR, -(sp) ; save this little mother <6/17/88ldc>
|
||
GetSMgrCore NflagsR ; get this for jump to AppendSymbol <6/17/88ldc>
|
||
move.l sVectAppendSymbol(NflagsR), NflagsR ; <6/21/88ldc>
|
||
|
||
ENDIF
|
||
|
||
@postDecWhile:
|
||
MOVE.B formCountR,D0 ;WHILE i < startLocs[nextFormatClass(formCount)]…
|
||
JSR NextFormatClass
|
||
ADD.W D0,D0
|
||
compw startLocs(myCanonicalR,D0.W),formPosR
|
||
SLT D0
|
||
AND.B mantissa(A6),D0 ;…AND mantissa DO
|
||
BEQ.S @endPosDecWhile
|
||
MOVE.W (destPosR),hold(A6) ;save our current destination position in case we need to cut
|
||
CLR.W D1
|
||
MOVE.B formString(myCanonicalR,formPosR.W),D1 ;get formString[formPosR]
|
||
MOVE.W D1,ch(A6) ;save it in ch
|
||
MOVE.W D1,-(A7) ;and push it for AppendSymbol
|
||
PEA postDec(A6)
|
||
PEA postDecFinal(A6)
|
||
PEA SendChar ;this time, it's not reversed
|
||
CLR.L -(A7)
|
||
MOVE.L A6,-(A7)
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
jsr (NflagsR) ; get from vector <6/17/88ldc>
|
||
ELSE
|
||
JSR AppendSymbol
|
||
ENDIF
|
||
|
||
MOVE.W lastSig(A6),D0 ;if our digit count has gone beyond lastSig,
|
||
compw digCnt(A6),D0 ;then we may have to cut
|
||
BGE.S @mergeAfterCut
|
||
MOVE.W ch(A6),D1
|
||
CMP.B #tokLeader,D1 ;if it's a leader but not nonLeader, then no cut
|
||
BEQ.S @noCutting
|
||
CMP.B #tokZeroLead,D1
|
||
BNE.S @maybeCut
|
||
@noCutting:
|
||
CLR.W startCut(A6) ;reset startCut because leaders nullify it
|
||
BRA.S @mergeAfterCut
|
||
@maybeCut:
|
||
CMP.B #tokNonLeader,D1 ;the only cutting possibility is if D1 is a nonLeader
|
||
BNE.S @setUpHold
|
||
ADDQ.W #1,D0
|
||
compw digCnt(A6),D0 ;but no cut if digCount has not exceeded lastSig
|
||
BGE.S @mergeAfterCut
|
||
MOVE.W startCut(A6),D1 ;if startCut is clear because somewhere along the line…
|
||
BNE.S @mergeSetSC ;…we hit a leader other than nonLead, we need to…
|
||
MOVE.W hold(A6),D1 ;…set the new startCut to the character we just appended
|
||
MOVE.W D1,startCut(A6)
|
||
@mergeSetSC:
|
||
MOVE.W D1,(destPosR) ;in any case, do the cut
|
||
BRA.S @mergeAfterCut
|
||
@setUpHold:
|
||
TST.W startCut(A6) ;test if startCut is zero
|
||
BNE.S @mergeAfterCut ;and if it's not then leave it alone
|
||
MOVE.W hold(A6),startCut(A6) ;otherwise set it to the character we just appended
|
||
@mergeAfterCut:
|
||
ADDQ.W #1,formPosR ;and finally, increment the position within the form string
|
||
BRA @postDecWhile
|
||
@endPosDecWhile:
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
move.l (sp)+, NflagsR ; restore after using for intlSpec <6/17/88ldc>
|
||
ENDIF
|
||
|
||
MOVE.W (destPosR),D0 ;now give a length to postDecFinal
|
||
SUBQ.W #1,D0
|
||
MOVE.B D0,postDecFinal(A6)
|
||
MOVE.W formPosR,expEnd(A6) ;expEnd is actually the beginning
|
||
MOVE.B formCountR,D0 ;formPos:= startLocs[nextFormatClass(formCount)]
|
||
JSR NextFormatClass ;that is the end of the formString for this format
|
||
ADD.W D0,D0
|
||
MOVE.W startLocs(myCanonicalR,D0.W),formPosR
|
||
SUBQ.W #1,formPosR
|
||
MOVE.W #1,(destPosR)
|
||
MOVE.W #1,digCnt(A6)
|
||
;<1/23/88drs> Added following 2 lines to correct bug.
|
||
;Optional digits in the exponent should act like digits in
|
||
;the pre-decimal significand
|
||
CLR.W penLastLead(A6)
|
||
CLR.W lastLead(A6)
|
||
MOVE.B mantissa(A6),D0 ;if we never hit the exponent then skip it
|
||
BEQ.S @doExponent
|
||
CLR.B expFinal(A6)
|
||
BRA.S @pastExponent
|
||
@doExponent:
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
|
||
move.l NflagsR, -(sp) ; store reg and get intlSpec <6/17/88ldc>
|
||
GetSMgrCore NflagsR ; AppendSymbol is now a vector <6/21/88ldc>
|
||
move.l sVectAppendSymbol(NflagsR), NflagsR
|
||
|
||
ENDIF
|
||
|
||
@expWhile:
|
||
compw expEnd(A6),formPosR ; WHILE formPosR >= expEnd
|
||
BLT.S @pastExpWhile
|
||
CLR.W D1
|
||
MOVE.B formString(myCanonicalR,formPosR.W),D1
|
||
MOVE.W D1,-(A7) ;push formString[formPos]
|
||
PEA exp(A6)
|
||
PEA expFinal(A6)
|
||
PEA SendCharRev ;reversed this time
|
||
CLR.L -(A7)
|
||
MOVE.L A6,-(A7)
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
jsr (NflagsR) ; <6/17/88ldc>
|
||
ELSE
|
||
JSR AppendSymbol ;send off this character
|
||
ENDIF
|
||
|
||
;<1/23/88drs> Added the following 5 lines to fix bug.
|
||
;Digits in the exponent should act like pre-decimal digits.
|
||
TST.W penLastLead(A6) ;if bracketed by nonLeaders then snip of the optional stuff
|
||
BEQ.S @noSnipExp
|
||
MOVE.W lastLead(A6),(destPosR)
|
||
CLR.W penLastLead(A6)
|
||
@noSnipExp:
|
||
SUBQ.W #1,formPosR ;decrement position in formString
|
||
BRA.S @expWhile
|
||
@pastExpWhile:
|
||
|
||
IF forRom THEN ; changed buildLevel>=2 to forRom <06/30/89 pke>
|
||
move.l (sp)+, NflagsR ; restore
|
||
ENDIF
|
||
|
||
MOVE.W (destPosR),D0 ;set the length of the expFinal string
|
||
SUBQ.W #1,D0
|
||
MOVE.B D0,expFinal(A6)
|
||
CLR.W D0
|
||
MOVE.B exp(A6),D0 ;if digCnt < ORD(exp[0]) then we blew it
|
||
compw digCnt(A6),D0
|
||
BLT.S @expOkSize
|
||
ST oversizedR
|
||
@mergePreDecV:
|
||
@pastExponent:
|
||
@expOkSize:
|
||
MOVE.B oversizedR,D0 ;did we ever get blimped?
|
||
BEQ.S @noSizeProblem
|
||
MOVE.W #fFormatOverflow,returnValue1(A6)
|
||
BRA @outTheDoor
|
||
@noSizeProblem:
|
||
MOVEA.L out(A6),A0 ;give out a maximum size to start with
|
||
MOVE.B #255,(A0)
|
||
MOVE.W #1,(destPosR) ;and reset destPosR
|
||
MOVE.B doNegative(A6),D0 ;if we need a negative sign then get one
|
||
BEQ.S @pastNegSign
|
||
CLR.W -(A7)
|
||
MOVE.W data+((tokMinusSign-tokLeftQuote)*2)(partsTableR),-(A7)
|
||
MOVE.L out(A6),-(A7)
|
||
MOVE.L destPosR,-(SP)
|
||
JSR SendChar
|
||
MOVE.W (A7)+,resR
|
||
@pastNegSign: ;the next 50,000 lines only copy…
|
||
;…preDecFinal,postDecFinal,and expFinal into out
|
||
CLR.W D0
|
||
MOVE.B preDecFinal(A6),D0
|
||
MOVE.W D0,formPosR
|
||
BRA.S @L227
|
||
@L228:
|
||
MOVEA.L out(A6),A0
|
||
MOVE.W (destPosR),D0
|
||
LEA preDecFinal(A6),A1
|
||
MOVE.B 0(A1,formPosR.W),0(A0,D0.W)
|
||
ADDQ.W #1,(destPosR)
|
||
SUBQ.W #1,formPosR
|
||
@L227:
|
||
compw #1,formPosR
|
||
BGE.S @L228
|
||
CLR.W D0
|
||
MOVE.B postDecFinal(A6),D0
|
||
MOVE.W D0,while1(A6)
|
||
MOVEQ #1,formPosR
|
||
BRA.S @L229
|
||
@L231:
|
||
MOVEA.L out(A6),A0
|
||
MOVE.W (destPosR),D0
|
||
LEA postDecFinal(A6),A1
|
||
MOVE.B 0(A1,formPosR.W),0(A0,D0.W)
|
||
ADDQ.W #1,(destPosR)
|
||
ADDQ.W #1,formPosR
|
||
@L229:
|
||
compw while1(A6),formPosR
|
||
BLE.S @L231
|
||
@L230:
|
||
CLR.W D0
|
||
MOVE.B expFinal(A6),D0
|
||
MOVE.W D0,formPosR
|
||
BRA.S @L232
|
||
@L233:
|
||
MOVEA.L out(A6),A0
|
||
MOVE.W (destPosR),D0
|
||
LEA expFinal(A6),A1
|
||
MOVE.B 0(A1,formPosR.W),0(A0,D0.W)
|
||
ADDQ.W #1,(destPosR)
|
||
SUBQ.W #1,formPosR
|
||
@L232:
|
||
compw #0,formPosR
|
||
bgt.s @L233 ; was bge 1 <2/7/88med>
|
||
|
||
BTST #fIsPercent,(NflagsR) ;are we dealing with a percent?
|
||
BEQ.S @afterPercent ;thank God no
|
||
CLR.W -(A7) ;otherwise tack it on too
|
||
MOVE.W data+((tokPercent-tokLeftQuote)*2)(partsTableR),-(A7)
|
||
MOVE.L out(A6),-(A7)
|
||
MOVE.L destPosR,-(SP)
|
||
JSR SendChar
|
||
MOVE.W (A7)+,resR
|
||
@afterPercent:
|
||
MOVEA.L out(A6),A0 ;give out a length
|
||
MOVE.W (destPosR),D0
|
||
SUBQ.W #1,D0
|
||
MOVE.B D0,(A0)
|
||
|
||
bra.s @outTheDoor ; <9/7/88ldc>
|
||
|
||
@returnNAN
|
||
move.w #fFormStrIsNAN, resR ; <9/8/88ldc>
|
||
bra.s @outTheDoor ; <9/8/88ldc>
|
||
|
||
@returnOverflow
|
||
move.w #fFormatOverflow, resR ; <9/8/88ldc>
|
||
bra.s @outTheDoor ; <9/8/88ldc>
|
||
|
||
@emptyFormatString
|
||
move.w #fEmptyFormatString, resR ; flag empty format string <9/7/88ldc>
|
||
|
||
@outTheDoor:
|
||
compw #fFormatOK, resR ;see if we ever blew it anywhere
|
||
BEQ.S @afterRes
|
||
MOVE.W resR,returnValue1(A6)
|
||
@afterRes:
|
||
MOVEM.L (A7)+,localRegs
|
||
|
||
move.w #argFrame1, d0 ; for StdUnlink
|
||
bra StdUnlink ; standard exit
|
||
|
||
CheckDebug 'FORMX2ST'
|
||
@c100: ;constant 100.0
|
||
DC.W $4005, $C800, $0000, $0000, $0000
|
||
|
||
ENDWITH
|
||
endp
|
||
end
|
||
|