Include a .cbmfloat pragma to make creating data simpler

Due to the usual vagaries of floating point, these are not completely
perfect, but for "human-scale" numbers it will be OK.
This commit is contained in:
Michael Martin 2014-05-18 23:19:22 -07:00
parent bfbe169364
commit d3772587da
4 changed files with 60 additions and 8 deletions

View File

@ -95,11 +95,11 @@ impact_point_2:
height_1: height_1:
.byte "MAXIMUM HEIGHT OF ",0 .byte "MAXIMUM HEIGHT OF ",0
f_0_125: .byte 126,0,0,0,0 f_0_125: .cbmfloat "0.125"
f_9_8: .byte 132,28,204,204,204 f_9_8: .cbmfloat "9.8"
f_90: .byte 135,52,0,0,0 f_90: .cbmfloat "90"
f_100: .byte 135,72,0,0,0 f_100: .cbmfloat "100"
f_180: .byte 136,52,0,0,0 f_180: .cbmfloat "180"
get_num: get_num:
.scope .scope

View File

@ -10,7 +10,7 @@ import Ophis.CmdLine
import Ophis.IR as IR import Ophis.IR as IR
import Ophis.Frontend as FE import Ophis.Frontend as FE
import Ophis.Errors as Err import Ophis.Errors as Err
import os.path import math, os.path
basecharmap = "".join([chr(x) for x in range(256)]) basecharmap = "".join([chr(x) for x in range(256)])
currentcharmap = basecharmap currentcharmap = basecharmap
@ -219,6 +219,40 @@ def pragmaData(ppt, line, result):
result.append(IR.Node(ppt, "DataSegment", segment)) result.append(IR.Node(ppt, "DataSegment", segment))
def pragmaCbmfloat(ppt, line, result):
"Parses a string into a CBM BASIC format floating point number"
data = []
while True:
try:
v_str = line.expect("STRING").value
v = float(v_str)
if v == 0.0:
data.extend([0,0,0,0,0])
else:
if v < 0.0:
sign = 128
v = -v
else:
sign = 0
expt = math.floor(math.log(v, 2))
if expt >= -128 and expt <= 126:
mantissa = v / (2**expt)
m1 = (mantissa - 1.0) * 128 + sign
m2 = m1 * 256
m3 = m2 * 256
m4 = m3 * 256
data.extend([int(x) % 256 for x in [expt+129,m1,m2,m3,m4]])
else:
Err.log("Floating point constant out of range")
except ValueError:
Err.log("Expected: floating point")
next = line.expect(',', 'EOL').type
if next == 'EOL':
break
bytes = [IR.ConstantExpr(x) for x in data]
result.append(IR.Node(ppt, "Byte", *bytes))
def readData(line): def readData(line):
"Read raw data from a comma-separated list" "Read raw data from a comma-separated list"
if line.lookahead(0).type == "STRING": if line.lookahead(0).type == "STRING":

Binary file not shown.

View File

@ -1,5 +1,5 @@
; This data file just dumps out $00-$0F repeatedly with different forms, ; This part of the file just dumps out $00-$0F repeatedly with
; bracketed by $00s and then $60s. ; different forms, bracketed by $00s and then $60s.
.advance $10, ^ .advance $10, ^
.byte 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 .byte 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
.word 256, $0302, $0504, $0706, $0908, $0b0a, $0d0c, $0f0e .word 256, $0302, $0504, $0706, $0908, $0b0a, $0d0c, $0f0e
@ -7,3 +7,21 @@
.wordbe 1, $0203, $0405, $0607, $0809, $0a0b, $0c0d, $0e0f .wordbe 1, $0203, $0405, $0607, $0809, $0a0b, $0c0d, $0e0f
.dwordbe $010203, $04050607, $08090a0b, $0c0d0e0f .dwordbe $010203, $04050607, $08090a0b, $0c0d0e0f
.advance $70, ^ .advance $70, ^
; To verify that that these numbers match up, we use the following
; BASIC program, which works on both the C64 and the VIC-20.
; 10 clr:v=0:pv=peek(45)+256*peek(46)+2
; 20 input "convert what";v
; 30 for i=0 to 4:print peek(pv+i);:next i
; 40 print:if v<>0 then 10
.cbmfloat "0.0", "0.125","9.8","90","100","180"
; The program tells us that these are the right answers.
; We'd like to test more exotic choices like the 4.3e12 or what have you,
; but the fact that these are two different kinds of floating point
; results in slight variations at the very bottom of the mantissa.
; caveat emptor.
; .byte 0,0,0,0,0,126,0,0,0,0,132,28,204,204,204,135,52,0,0,0
; .byte 135,72,0,0,0,136,52,0,0,0