aboutsummaryrefslogtreecommitdiff
path: root/parameters.go
blob: 02991cf99c100c0e37981269999c46c8ef86713e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package main

import (
	"fmt"
	"strconv"
	"strings"
)

func Reg8(_ *ProgramState, param string) (uint16, error) {
	switch param {
	case "A":
		return 7, nil
	case "B":
		return 0, nil
	case "C":
		return 1, nil
	case "D":
		return 2, nil
	case "E":
		return 3, nil
	case "H":
		return 4, nil
	case "L":
		return 5, nil
	case "(HL)":
		return 6, nil
	}
	return 0, fmt.Errorf("Invalid reg8")
}

func A(_ *ProgramState, param string) (uint16, error) {
	if param == "A" {
		return 0, nil
	}
	return 0, fmt.Errorf("Invalid A")
}

func HL(_ *ProgramState, param string) (uint16, error) {
	if param == "HL" {
		return 0, nil
	}
	return 0, fmt.Errorf("Invalid HL")
}

func SP(_ *ProgramState, param string) (uint16, error) {
	if param == "SP" {
		return 0, nil
	}
	return 0, fmt.Errorf("Invalid SP")
}

func IndirectC(_ *ProgramState, param string) (uint16, error) {
	if param == "(C)" {
		return 0, nil
	}
	return 0, fmt.Errorf("Invalid (C)")
}

func Reg16(_ *ProgramState, param string) (uint16, error) {
	switch param {
	case "BC":
		return 0, nil
	case "DE":
		return 1, nil
	case "HL":
		return 2, nil
	case "AF":
		return 3, nil
	// TODO Split in two different for push and not push instructions
	case "SP":
		return 3, nil
	}
	return 0, fmt.Errorf("Invalid reg16")
}

func Raw8(_ *ProgramState, param string) (uint16, error) {
	res, err := strconv.ParseInt(param, 0, 8)
	return uint16(res), err
}

func Raw16(state *ProgramState, param string) (uint16, error) {
	res, err := strconv.ParseInt(param, 0, 16)

	if strings.HasPrefix(param, "=") {
		if state == nil {
			return 0, nil
		}

		label := strings.ToUpper(strings.TrimPrefix(param, "="))
		labelValue, ok := state.Labels[label]
		if !ok {
			return 0, fmt.Errorf("Label \"%s\" not found", label)
		}

		// TODO: Manage when multiple MBC
		if labelValue > 0x8000 {
			panic("Switchable ROM banks are not implemented yet")
		}

		return uint16(labelValue), nil
	}

	return uint16(res), err
}

func Reg16Indirect(_ *ProgramState, param string) (uint16, error) {
	switch param {
	case "(BC)":
		return 0, nil
	case "(DE)":
		return 1, nil
	case "(HL+)":
		return 2, nil
	case "(HL-)":
		return 3, nil
	}
	return 0, fmt.Errorf("Invalid reg16 indirect")
}

func Raw8Indirect(_ *ProgramState, param string) (uint16, error) {
	if len(param) < 2 || param[0] != '(' || param[len(param)-1] != ')' {
		return 0, fmt.Errorf("Invalid raw8indirect")
	}

	res, err := strconv.ParseInt(param[1:len(param)-1], 0, 8)
	return uint16(res), err
}

func Raw16Indirect(_ *ProgramState, param string) (uint16, error) {
	if len(param) < 2 || param[0] != '(' || param[len(param)-1] != ')' {
		return 0, fmt.Errorf("Invalid raw16indirect")
	}

	res, err := strconv.ParseInt(param[1:len(param)-1], 0, 16)
	return uint16(res), err
}

func Condition(_ *ProgramState, param string) (uint16, error) {
	switch param {
	case "NZ":
		return 0, nil
	case "Z":
		return 1, nil
	case "NC":
		return 2, nil
	case "C":
		return 3, nil
	}
	return 0, fmt.Errorf("Invalid condition")
}

func BitOrdinal(_ *ProgramState, param string) (uint16, error) {
	res, err := strconv.ParseInt(param, 0, 3)
	return uint16(res), err
}