diff --git a/source/common/aa.system/04data.inc b/source/common/aa.system/04data.inc index 6fba5624..2ff1c790 100644 --- a/source/common/aa.system/04data.inc +++ b/source/common/aa.system/04data.inc @@ -1,27 +1,12 @@ -; ************************************************************************************************ -; ************************************************************************************************ -; -; Name: 04data.inc -; Purpose: Main Data -; Created: 18th September 2022 -; Reviewed: 23rd November 2022 -; Author: Paul Robson (paul@robsons.org.uk) -; -; ************************************************************************************************ -; ************************************************************************************************ -; ************************************************************************************************ -; -; Mandatory Zero page code -; -; ************************************************************************************************ +; Mandatory zero-page data .section zeropage codePtr: ; address of current line (allow for 32 bit) .fill 4 basicStack: ; BASIC stack address - .fill 2 + .fill 2 zTemp0: ; temporary words used in the interpreter. .fill 2 zTemp1: @@ -32,61 +17,68 @@ zsTemp: ; allocated string temporary. .fill 2 zaTemp: ; allocated array temporary .fill 2 - + safePtr = codePtr ; minimise direct tinkering - - .send zeropage -; ************************************************************************************************ -; -; Preferable Zero page code -; -; ************************************************************************************************ + .send zeropage -NSBIsNegative = $80 ; bit 7 : sign of mantissa (where numeric) -NSBIsReference = $20 ; bit 5 : is a reference -NSBIsString = $10 ; bit 4 : set if string (procedures don't go on the stack) -NSBTypeMask = $18 ; bits 4,3 : 00 int 01 float 10 string 11 procedure -NSBRefMask = $03 ; bits 0,1 : Bytes of reference, 00 = 4,01 = 1,10=2 -NSBIsArray = $04 -NSTInteger = $00 ; base types for bits 3..4 -NSTFloat = $08 -NSTString = $10 -NSTProcedure = $18 +; Preferably zero-page data .section zeropref -; ************************************************************************************************ -; -; The number stack (works up from zero) -; -; ************************************************************************************************ +; Number stack status masks +NSBIsNegative = $80 ; bit 7: sign of mantissa (where numeric) +NSBIsReference = $20 ; bit 5: is a reference +NSBIsString = $10 ; bit 4: set if string (procedures don't go on the stack) +NSBTypeMask = $18 ; bits 4,3: 00 int 01 float 10 string 11 procedure +NSBRefMask = $03 ; bits 0,1: Bytes of reference, 00 = 4,01 = 1,10=2 +NSBIsArray = $04 + +NSTInteger = $00 ; base types for bits 3..4 +NSTFloat = $08 +NSTString = $10 +NSTProcedure = $18 + +;; +; The number stack (works up from zero) +;; NSStatus: ; Status bits of stack. .fill MathStackSize -NSMantissa0: ; Mantissa on stack (address in 0,1 for string/reference) - .fill MathStackSize ; (this is my integer mantissa system) -NSMantissa1: ; the order of the mantissa elements is required. + +; 4 mantissa bytes (little-endian, 31 bits + sign) +; +; Stores an integer magnitude. Normalized non-zero mantissa always has bit 30 set. +; +; Note that on the number stack, the sign is kept in `NSStatus` (`NSBIsNegative` mask), so the +; mantissa itself only carries magnitude; when a float is written out to a variable, the sign +; bit gets packed into the top bit of the highest mantissa byte. +NSMantissa0: + .fill MathStackSize +NSMantissa1: .fill MathStackSize NSMantissa2: .fill MathStackSize NSMantissa3: .fill MathStackSize -NSExponent: ; Exponent , 0 = Mantissa is integer + + +; a signed 8-bit base-2 exponent stored in two's complement format; 0 if mantissa is integer +; +; floating-point value = mantissa x 2^decoded exponent, where +; decoded exponent = exponent if exponent < 128 else exponent - 256 +NSExponent: .fill MathStackSize -fnStackLevel: ; saved stack level for function evaluation +; saved stack level for function evaluation +fnStackLevel: .fill 1 .send zeropref -; ************************************************************************************************ -; -; Non Zero Page Data -; -; ************************************************************************************************ +; Non-zero page data .section storage @@ -95,7 +87,7 @@ identStart: ; start of identifier in line buffer identTypeStart: ; start of type information (#$ and ( in the line buffer) .fill 1 identTypeEnd: ; character after end of type information in the line buffer - .fill 1 + .fill 1 identHash: ; hash of identifier (including the type characters) .fill 1 identTypeByte: ; type descriptor in format used in identifier record @@ -113,43 +105,43 @@ lowMemPtr: ; memory allocation after program. arrayMemPtr: ; array/alloc storage pointer (slots 2-3, $4000-$7FFF) .fill 2 stringMemory: ; allocate concrete strings from here - .fill 2 -stringInitialised: ; string - .fill 1 + .fill 2 +stringInitialised: ; string + .fill 1 stringTempPointer: ; temporary string - .fill 2 + .fill 2 breakCheck: ; break check counter/shift .fill 1 - + decimalPlaces: ; no of decimals. .fill 1 dbOffset: ; offset into decimal buffer. - .fill 1 + .fill 1 lastParameter: ; final stack offset when all parameters handled. .fill 1 - + dataPointer: ; operates like code pointer for DATA statements .fill 5 inDataStatement: ; non zero when in data statement, e.g. pointing to data - .fill 1 + .fill 1 tbOffset: ; offset into token buffer - .fill 1 + .fill 1 AssemblerAddress: ; address being assembled at .fill 2 AssemblerControl: ; assembler control byte - bit 0 (errors ok), bit 1 (listing on) - .fill 1 + .fill 1 ParamStart: ; offset of parameter. - .fill 2 + .fill 2 IsGroup1: ; flag set if group.1 - .fill 1 + .fill 1 BaseOpcode: ; base opcode - .fill 1 + .fill 1 ModeMask: ; modes allowed - .fill 1 + .fill 1 listIndent: ; list indent level. .fill 1 listElseFound: ; flag set when ELSE found on line (for indent fix) @@ -157,19 +149,19 @@ listElseFound: ; flag set when ELSE found on line (for indent fix) listEndToken: ; closing token for LIST proc/fn .fill 1 lcLastCharacter: ; last character output. - .fill 1 + .fill 1 isPrintFlag: ; zero if input, non-zero if print, bit 6 zero = character print - .fill 1 + .fill 1 currentListColour: ; current set colour when listing. .fill 1 ; ; New tokenised line - these three *must* be contiguous as they are used as a single entity -; +; tokenOffset: ; used for tokenising - tokenised result goes here - .fill 1 + .fill 1 tokenLineNumber: - .fill 2 -tokenBuffer: + .fill 2 +tokenBuffer: .fill 253 lineBuffer: ; used for input - ASCII line goes here @@ -193,19 +185,3 @@ decimalBuffer: ; buffer for number -> string conversion. .fill 24 .send storage - -; ************************************************************************************************ -; -; Changes and Updates -; -; ************************************************************************************************ -; -; Date Notes -; ==== ===== -; 1/12/2022 Changed the recorded values used in the reference byte size which were -; incorrect, no code change. -; 2/12/2022 Made line buffer long again, as long lines can be entered via cross -; development which would crash the interpreter. -; -; ************************************************************************************************ - diff --git a/source/common/expressions/float/integer.asm b/source/common/expressions/float/integer.asm index 5cf3590e..325f9944 100644 --- a/source/common/expressions/float/integer.asm +++ b/source/common/expressions/float/integer.asm @@ -1,60 +1,46 @@ -; ************************************************************************************************ -; ************************************************************************************************ -; -; Name: integer.asm -; Purpose: Make FPA Denormalised integer -; Created: 29th September 2022 -; Reviewed: 28th November 2022 -; Author : Paul Robson (paul@robsons.org.uk) -; -; ************************************************************************************************ -; ************************************************************************************************ .section code -; ************************************************************************************************ +;; +; Convert floating-point entry at position X in the number stack to an +; integer. ; -; Make FPA into an integer -; -; ************************************************************************************************ - +; Sets carry if the value was not already an exact integer. +;; FloatIntegerPart: pha - ; + phy + ldy #$0 ; store the carry status in Y + lda NSExponent,x ; is it integer already ? - beq _FIPExit ; if so do nothing + beq _exit ; if so do nothing jsr NSMIsZero ; is it zero ? - beq _FIPZero ; if so return zero. - ; + beq _zero ; if so return zero. + jsr NSNormalise ; normalise - beq _FIPZero ; normalised to zero, exit zero - ; -_FIPShift: + beq _zero ; normalised to zero, exit zero + + _shift: lda NSExponent,x ; if Exponent >= 0 exit. - bpl _FIPCheckZero + bpl _check_zero jsr NSMShiftRight ; shift mantissa right - inc NSExponent,x ; bump exponent - bra _FIPShift + bcc + + ldy #$1 ; record that we lost a non-zero bit ++ inc NSExponent,x ; bump exponent + bra _shift -_FIPCheckZero: + _check_zero: jsr NSMIsZero ; avoid -0 problem - bne _FIPExit ; set to zero if mantissa zero. -_FIPZero: + bne _exit ; set to zero if mantissa zero. + + _zero: jsr NSMSetZero -_FIPExit: + + _exit: + cpy #$1 ; sets the carry flag if Y is 1 + ply pla - rts + rts .send code - -; ************************************************************************************************ -; -; Changes and Updates -; -; ************************************************************************************************ -; -; Date Notes -; ==== ===== -; -; ************************************************************************************************ diff --git a/source/common/expressions/float/utility.asm b/source/common/expressions/float/utility.asm index cb9c15b8..e9029715 100644 --- a/source/common/expressions/float/utility.asm +++ b/source/common/expressions/float/utility.asm @@ -28,19 +28,20 @@ FloatPrepare: _FDType: jmp TypeError -; ************************************************************************************************ -; -; Normalise Stack[X] + +;; +; Normalize floating-point entry at position X in the number stack. ; -; ************************************************************************************************ +; \in X Index of the entry in the number stack. +;; NSNormalise: lda NSStatus,x ; make float, keep sign and #$80 - ora #NSTFloat + ora #NSTFloat sta NSStatus,x - jsr NSMIsZero ; if zero exit + jsr NSMIsZero ; if zero exit bne _NSNormaliseOptimise ; if so, normalise it. asl NSStatus,x ; clear the sign bit. ror NSStatus,x ; (no -0) @@ -50,7 +51,7 @@ NSNormalise: ; Normalise by byte if the MSB is zero we can normalise it ; (providing bit 7 of 2nd byte is not set) ; -_NSNormaliseOptimise: +_NSNormaliseOptimise: lda NSMantissa3,x ; upper byte zero ? bne _NSNormaliseLoop lda NSMantissa2,x ; byte normalise @@ -71,7 +72,7 @@ _NSNormaliseOptimise: ; ; Normalise by bit ; -_NSNormaliseLoop: +_NSNormaliseLoop: bit NSMantissa3,x ; bit 30 set ? bvs _NSNExit ; exit if so with Z flag clear jsr NSMShiftLeft ; shift mantissa left @@ -82,7 +83,7 @@ _NSNExit: rts .send code - + ; ************************************************************************************************ ; ; Changes and Updates diff --git a/source/common/expressions/term/assignnumber.asm b/source/common/expressions/term/assignnumber.asm index 52e8399a..2ac09420 100644 --- a/source/common/expressions/term/assignnumber.asm +++ b/source/common/expressions/term/assignnumber.asm @@ -37,12 +37,15 @@ AssignNumber: ; lda NSExponent+1,x ; is it a float beq _ANNotFloat -; inx -; jsr FloatIntegerPart ; make it an integer (disabled) -; dex - jmp RangeError ; if it is, report an error. -_ANNotFloat: + ; check if the float argument is in fact an integer + inx + jsr FloatIntegerPart ; convert it to an integer + dex + bcc _ANNotFloat ; no digits were lost, okay to proceed + jmp TypeError ; it was, in fact, a float, report an error + +_ANNotFloat: lda NSStatus,x ; check if byte/word reference. and #3 bne _ANByteWord @@ -50,7 +53,7 @@ _ANNotFloat: ; 4 byte integer assign ; jsr _ANCopy4PackSign ; copy all 4 bytes and sign - bra _ANExit + bra _ANExit ; ; 1 or 2 byte/word assign ; @@ -70,19 +73,19 @@ _ANByteWord: ; Assign a float ; _ANFloat: - jsr _ANCopy4PackSign ; write all 4 bytes and packed sign + jsr _ANCopy4PackSign ; write all 4 bytes and packed sign lda NSExponent+1,x ; copy exponent to slot 4 ldy #4 - sta (zTemp0),y + sta (zTemp0),y _ANExit: ply - rts + rts ; ; Copy all 4 bytes, with sign bit, from (zTemp),y+3 ; _ANCopy4PackSign: ldy #3 - lda NSStatus+1,x ; sign bit into status + lda NSStatus+1,x ; sign bit into status and #$80 ; put into high bit of mantissa 3 ora NSMantissa3+1,x sta (zTemp0),y