Python 3, 421 414 410 404 388388 395 bytes
import sys,re
v,i,c,g,L={},0,[re.sub('[^9]+',' ',l).rstrip().split(' ')for l in open(sys.argv[1])],lambda i:v.get(i,int(i)//9),len
while-1<i<L(c):
d=c[i];l=L(d);e,*f=d;i+=1
if l>1:
x,*y=f
if e:w=list(map(g,f));v[e]=sum(w[::2])-sum(w[1::2])
elif l==2:j=input();v[x]=int(j)if L(x)%2 else ord(j)
elif~-any(g(j)for j in y):i=g(x)*9
elif e:w=g(e);print(w if L(e)%2 else chr(w%128),end='')
import sys, re
# Intialise variable table.
vars_ = {}
get_var = lambda i: vars_.get(i, int(i)//9)
# Parse commands.
commands=[re.sub('[^9]+', ' ', l).rstrip().split(' ') for l in open(sys.argv[1])]
# Run until the current instruction index is out of bounds.
index=0
while 0 <= index < len(commands):
# Get the current command and increment the index.
command = commands[index]
l = len(command)
first = command[0]
index += 1
if l > 1:
# Handle the "assignment" command.
if first:
operands = [get_var(i) for i in command[1:]]
vars_[first] = sum(operands[0::2]) - sum(operands[1::2])
# Handle the "input" command.
elif l==2:
inp = input()
vars_[command[1]] = int(inp) if len(command[1]) % 2 else ord(inp)
# Handle the "goto" command.
elif not any(get_var(i) for i in command[2:]):
index = get_var(command[1]) * 9
# Handle the "output" command.
elif first:
val = get_var(first)
print(val if len(first) % 2 else chr(val % 128),end='')
The "output" command outputs values with trailing linebreaks (unlike the examples in the OP), but I'm assuming that's ok based on the caveats in the "additional details" section. If not, that can be fixed using sys.stdout.write(str(...))
instead of print(...)
for a 16 byte penalty.
Run from the command line by supplying a 99 source-code file as the sole argument (e.g. the last example from the OP):
> python3 ninetynine.py countdown.txt
G
11
G
10
G
9
G
8
G
7
G
6
G
5
G
4
G
3
G
2
G
1
GG11G10G9G8G7G6G5G4G3G2G1G
>