diff options
author | Astatin <[email protected]> | 2025-03-13 19:10:05 +0900 |
---|---|---|
committer | Astatin <[email protected]> | 2025-03-13 19:10:05 +0900 |
commit | 6438a2c98fedada7b04ab2c6d970da6710f6e703 (patch) | |
tree | b88c77a51675830fdca33f8813233de9f66946cf | |
parent | 8c60c8cf7acb3563b31d9d17ba1303efe3f0aa39 (diff) |
Enable offsets for all raw16 & raw8
-rw-r--r-- | parameters.go | 102 |
1 files changed, 73 insertions, 29 deletions
diff --git a/parameters.go b/parameters.go index 21930c2..48d053d 100644 --- a/parameters.go +++ b/parameters.go @@ -6,6 +6,26 @@ import ( "strings" ) +func parseOffset(param string) (string, uint16, error) { + if strings.Contains(param, "+") { + labelParts := strings.Split(param, "+") + if len(labelParts) != 2 { + return "", 0, fmt.Errorf( + "Labels with offset should have exactly 1 offset (in \"%s\")", + param, + ) + } + labelWithoutOffset := labelParts[0] + o, err := strconv.ParseUint(labelParts[1], 0, 16) + if err != nil { + return "", 0, fmt.Errorf("Error while parsing label offset: %w", err) + } + offset := uint16(o) + return labelWithoutOffset, offset, nil + } + return param, 0, nil +} + func Reg8(_ *Labels, lastAbsoluteLabel string, _ *Definitions, param string) (uint16, error) { switch param { case "A": @@ -97,24 +117,43 @@ func Raw8( param = strings.ToUpper(strings.TrimPrefix(param, "$")) if res, err := strconv.ParseUint(param, 16, 16); err == nil { if len(param) > 2 { - return 0, fmt.Errorf("%s is > 8bit precision", param) + return 0, fmt.Errorf("%s is > 8bit", param) } return uint16(res), nil } - definition, ok := (*defs)[param] + varWithoutOffset, offset, err := parseOffset(param) + if err != nil { + return 0, err + } + + definition, ok := (*defs)[varWithoutOffset] if !ok { - return 0, fmt.Errorf("$%s is undefined", param) + return 0, fmt.Errorf("$%s is undefined", varWithoutOffset) } res, ok := definition.(Raw8b) if !ok { - return 0, fmt.Errorf("$%s is of type %T but Raw8b is expected", param, res) + return 0, fmt.Errorf( + "$%s is of type %T but Raw8b is expected", + varWithoutOffset, + definition, + ) } - return uint16(res), nil + + if uint16(res)+offset > 0xff { + return 0, fmt.Errorf( + "overflow: $%s (0x%02x) + 0x%02x exceeds 0xff", + varWithoutOffset, + uint16(res), + offset, + ) + } + + return uint16(res) + offset, nil } if strings.HasPrefix(param, "0x") && len(param) > 4 { - return 0, fmt.Errorf("%s is > 8bit precision", param) + return 0, fmt.Errorf("%s is > 8bit", param) } res, err := strconv.ParseUint(param, 0, 8) return uint16(res), err @@ -132,36 +171,41 @@ func Raw16( return uint16(res), nil } - definition, ok := (*defs)[param] + varWithoutOffset, offset, err := parseOffset(param) + if err != nil { + return 0, err + } + + definition, ok := (*defs)[varWithoutOffset] if !ok { - return 0, fmt.Errorf("$%s is undefined", param) + return 0, fmt.Errorf("$%s is undefined", varWithoutOffset) } res, ok := definition.(Raw16b) if !ok { - return 0, fmt.Errorf("$%s is of type %T but Raw16b is expected", param, res) + return 0, fmt.Errorf( + "$%s is of type %T but Raw16b is expected", + varWithoutOffset, + definition, + ) } - return uint16(res), nil + + if uint32(res)+uint32(offset) > 0xffff { + return 0, fmt.Errorf( + "overflow: $%s (0x%04x) + 0x%04x exceeds 0xffff", + varWithoutOffset, + uint16(res), + offset, + ) + } + + return uint16(res) + offset, nil } if strings.HasPrefix(param, "=") { - var offset uint16 = 0 - labelWithoutOffset := param[1:] - - if strings.Contains(param, "+") { - labelParts := strings.Split(param[1:], "+") - if len(labelParts) != 2 { - return 0, fmt.Errorf( - "Labels with offset should have exactly 1 offset (in \"%s\")", - param[1:], - ) - } - labelWithoutOffset = labelParts[0] - o, err := strconv.ParseUint(labelParts[1], 0, 16) - if err != nil { - return 0, fmt.Errorf("Error while parsing label offset: %w", err) - } - offset = uint16(o) + labelWithoutOffset, offset, err := parseOffset(param[1:]) + if err != nil { + return 0, err } if labels == nil { @@ -247,7 +291,7 @@ func Raw8Indirect( res, ok := definition.(Indirect8b) if !ok { - return 0, fmt.Errorf("$%s is of type %T but Indirect8bb is expected", param, res) + return 0, fmt.Errorf("$%s is of type %T but Indirect8bb is expected", param, definition) } return uint16(res), nil } @@ -283,7 +327,7 @@ func Raw16Indirect( res, ok := definition.(Indirect16b) if !ok { - return 0, fmt.Errorf("$%s is of type %T but Indirect16b expected", param, res) + return 0, fmt.Errorf("$%s is of type %T but Indirect16b expected", param, definition) } return uint16(res), nil } |