/orig/Apple_DOS_v3.3_1980_Apple.do
/orig/DOS_Tool_Kit_v1.0_1980_Apple.do
/orig/Lemonade_Stand_1979_Apple.do
+/ribbit/bootable.dsk
+/ribbit/ribbit.bas
+/ribbit/ribbit_tone.asm
+/ribbit/ribbit_patched.bas
+/ribbit/ribbit_patched.dsk
/test/bootable.dsk
/test/lemonade_music.bas
/tok_to_bas.py
0xf, # white -> intense white
]
+# see ribbit.bas
+RBOOT_ENTRY = 0x208
+RLOAD_START = 0xb000 # for now
+RLOAD_ENTRY = 0xb003 # for now
+
# see lemonade_tone.lst
LEMONADE_TONE_PERIOD = 0x300
LEMONADE_TONE_DUR = 0x301
-LEMONADE_TONE_TONE = 0x302
+LEMONADE_TONE_ENTRY = 0x302
# see little_brick_out_tone.lst
LITTLE_BRICK_OUT_TONE_PERIOD = 6
LITTLE_BRICK_OUT_TONE_DUR = 7
-LITTLE_BRICK_OUT_TONE_TONE = 0x300
+LITTLE_BRICK_OUT_TONE_ENTRY = 0x300
# see tone.lst
TONE_REST = 0x300
HW_PB2: 0,
}
pdl_value = [255 for i in range(4)]
-gr_on = False
+current_gr = False
+current_speed = 255
def init():
global termios_attr, pcm
)
low_mem[addr + low_mem[ZP_CH]] = data
- if gr_on and low_mem[ZP_CV] < 20:
+ if current_gr and low_mem[ZP_CV] < 20:
write(gr_encode([data])[0] + invflg())
else:
write(ch)
if low_mem[ZP_CH] >= low_mem[ZP_WNDLFT] + low_mem[ZP_WNDWTH]:
crlf()
+ if current_speed < 255:
+ time.sleep((255 - current_speed) / 2550.) # up to .1s
+
def get_internal():
global ch_in
global flash_color0
addr &= 0xffff
- if addr == LITTLE_BRICK_OUT_TONE_TONE:
+ if addr == RBOOT_ENTRY:
+ pass
+ elif addr == RLOAD_ENTRY:
+ pass
+ elif addr == LITTLE_BRICK_OUT_TONE_ENTRY:
# for little brick out, see test/little_brick_out_tone.py
period_count = ((low_mem[LITTLE_BRICK_OUT_TONE_PERIOD] - 1) & 0xff) + 1
duration_count = ((low_mem[LITTLE_BRICK_OUT_TONE_DUR] - 1) & 0xff) + 1
# tone(1. / period, duration)
#else:
# time.sleep(duration)
- elif addr == LEMONADE_TONE_TONE:
+ elif addr == LEMONADE_TONE_ENTRY:
# for lemonade, see test/lemonade_tone.py
period_count = ((low_mem[LEMONADE_TONE_PERIOD] - 1) & 0xff) + 1
duration_count = ((low_mem[LEMONADE_TONE_DUR] - 1) & 0xff) + 1
return 0x400 | ((y & 7) << 7) | ((y >> 3) * 40)
def text():
- global gr_on
+ global current_gr
# save cursor, set scrolling region, restore cursor
write('\x1b[s\x1b[1;24r\x1b[u')
low_mem[ZP_WNDWTH] = 40
low_mem[ZP_WNDTOP] = 0
low_mem[ZP_WNDBTM] = 24
- gr_on = False
+ current_gr = False
def gr():
- global gr_on
+ global current_gr
# clear screen, set scrolling region (homes cursor)
#write(f'\x1b[2J\x1b[21;24r\x1b[1;21H')
for i in range(20):
addr = bascalc(i)
low_mem[addr:addr + 40] = [0] * 40
- gr_on = True
+ current_gr = True
# takes memory encoded with upper pixel in bits 0-3, lower in bits 4-7
# returns a stream of unicode characters with attribute-setting escapes
addr = bascalc(i)
data, attr = (
gr_encode(low_mem[addr + x0:addr + x1], attr)
- if gr_on and i < 20 else
+ if current_gr and i < 20 else
text_encode(low_mem[addr + x0:addr + x1], attr)
)
write(f'\x1b[{i + 1:d};{x0 + 1:d}H{data:s}')
gr_update(x, y0 >> 1, x + 1, (y1 >> 1) + 1)
def usr(n):
- return 0
+ # for ribbit (HRCG)
+ return RLOAD_START
def scrn(x, y):
i = y & 1
def pos():
return low_mem[ZP_CH]
+
+def speed(n):
+ global current_speed
+ current_speed = n & 0xff
k = 0,
l = 1,
m = 0,
- clicks = 0
+ clicks = 0,
+ onerr = -1
):
self.program = program if program is not None else Program()
self.variables = variables if variables is not None else {}
# count peek(-16336) within a statement, convert to a tone
self.clicks = clicks
+ # program index for ONERR GOTO (not used for anything yet)
+ self.onerr = onerr
+
def run(self):
try:
self.execute()
self.variables[name] = variable
return variable
- def find_array(self, name):
- # array is created and initialized to 11 0s if not existent
+ def find_array(self, name, n_dim):
+ # array is created with 11^n_dim zeroed entries if non-existent
array = self.arrays.get(name)
if array is None:
null_value = '' if name[-1] == '$' else 0 if name[-1] == '%' else 0.
- array = [Variable(null_value) for i in range(11)]
+ def create_array(i):
+ return (
+ Variable(null_value)
+ if i >= n_dim else
+ [create_array(i + 1) for j in range(11)]
+ )
+ array = create_array(0)
self.arrays[name] = array
return array
assert False
@method(StatementHGR)
def execute(self, context):
- assert False
+ # for ribbit (HRCG)
+ pass
@method(StatementHColorEqual)
def execute(self, context):
assert False
apple_io.lomem(value)
@method(StatementOnErr)
def execute(self, context):
- assert False
+ context.onerr = context.find_line(self.children[0].int_value)
@method(StatementResume)
def execute(self, context):
assert False
assert False
@method(StatementSpeedEqual)
def execute(self, context):
- assert False
+ value = self.children[0].get_int(context)
+ if value < 0:
+ raise Exception(
+ f'?ILLEGAL QUANTITY ERROR IN {context.line_number():d}'
+ )
+ apple_io.speed(value)
@method(StatementLet)
def execute(self, context):
value = self.children[1].get(context)
@method(LValueArray)
def find_variable(self, context):
name = self.children[0].str_value
- variable = context.find_array(name)
+ variable = context.find_array(name, len(self.children) - 1)
for i in self.children[1:]:
if not isinstance(variable, list):
# too many subscripts
| %space (?E{t_def.StatementVLin}TOKEN_VLIN rvalue ',' rvalue TOKEN_AT rvalue)
| %space (?E{t_def.StatementHGR2}TOKEN_HGR2)
| %space (?E{t_def.StatementHGR}TOKEN_HGR)
- | %space (?E{t_def.StatementHColorEqual}TOKEN_HCOLOR_EQUAL)
+ | %space (?E{t_def.StatementHColorEqual}TOKEN_HCOLOR_EQUAL rvalue)
| %space (?E{t_def.StatementHPlot}TOKEN_HPLOT)
| %space (?E{t_def.StatementDraw}TOKEN_DRAW)
| %space (?E{t_def.StatementXDraw}TOKEN_XDRAW)
| %space (?E{t_def.StatementHTab}TOKEN_HTAB rvalue)
| %space (?E{t_def.StatementHome}TOKEN_HOME)
- | %space (?E{t_def.StatementRotEqual}TOKEN_ROT_EQUAL)
- | %space (?E{t_def.StatementScaleEqual}TOKEN_SCALE_EQUAL)
+ | %space (?E{t_def.StatementRotEqual}TOKEN_ROT_EQUAL rvalue)
+ | %space (?E{t_def.StatementScaleEqual}TOKEN_SCALE_EQUAL rvalue)
| %space (?E{t_def.StatementShLoad}TOKEN_SHLOAD)
| %space (?E{t_def.StatementTrace}TOKEN_TRACE)
| %space (?E{t_def.StatementNoTrace}TOKEN_NOTRACE)
| %space (?E{t_def.StatementVTab}TOKEN_VTAB rvalue)
| %space (?E{t_def.StatementHimemColon}TOKEN_HIMEM_COLON rvalue)
| %space (?E{t_def.StatementLomemColon}TOKEN_LOMEM_COLON rvalue)
- | %space (?E{t_def.StatementOnErr}TOKEN_ONERR)
+ | %space (?E{t_def.StatementOnErr}TOKEN_ONERR TOKEN_GOTO INT_LITERAL)
| %space (?E{t_def.StatementResume}TOKEN_RESUME)
| %space (?E{t_def.StatementRecall}TOKEN_RECALL)
| %space (?E{t_def.StatementStore}TOKEN_STORE)
- | %space (?E{t_def.StatementSpeedEqual}TOKEN_SPEED_EQUAL)
+ | %space (?E{t_def.StatementSpeedEqual}TOKEN_SPEED_EQUAL rvalue)
| %space (?E{t_def.StatementLet}lvalue TOKEN_EQUAL rvalue)
| %space (?E{t_def.StatementLet}TOKEN_LET lvalue TOKEN_EQUAL rvalue)
| %space (?E{t_def.StatementGoto}TOKEN_GOTO INT_LITERAL)
| %space (?E{t_def.RValueSgn}TOKEN_SGN '(' rvalue ')')
| %space (?E{t_def.RValueInt}TOKEN_INT '(' rvalue ')')
| %space (?E{t_def.RValueAbs}TOKEN_ABS '(' rvalue ')')
- | %space (?E{t_def.RValueUsr}TOKEN_USR '(' rvalue ')')
+ | %space (?E{t_def.RValueUsr}TOKEN_USR '(' rvalue ')' ',' STR_LITERAL)
| %space (?E{t_def.RValueFre}TOKEN_FRE '(' rvalue ')')
| %space (?E{t_def.RValueScrnLParen}TOKEN_SCRN_LPAREN rvalue ',' rvalue ')')
| %space (?E{t_def.RValuePdl}TOKEN_PDL '(' rvalue ')')
--- /dev/null
+DOS33=../dos33fsprogs/utils/dos33fs-utils/dos33
+MKDOS33FS=../dos33fsprogs/utils/dos33fs-utils/mkdos33fs
+TOK_TO_BIN=../tok_to_bin.py
+BIN_TO_TOK=../bin_to_tok.py
+TOK_TO_BAS=../tok_to_bas.py
+BAS_TO_TOK=../bas_to_tok.py
+
+.PHONY: all
+all: ribbit_patched.dsk ribbit_tone.obj
+
+ribbit_patched.dsk: ribbit_patched.bin tone.obj bootable.dsk
+ cp bootable.dsk $@
+ ${DOS33} $@ DELETE HELLO
+ ${DOS33} $@ SAVE A ribbit_patched.bin "RIBBIT PATCHED"
+ ${DOS33} $@ SAVE B tone.obj TONE.OBJ
+ ${DOS33} $@ HELLO "RIBBIT PATCHED"
+
+ribbit_patched.bin: ribbit_patched.tok
+ ${TOK_TO_BIN} <$< >$@
+
+ribbit_patched.tok: ribbit_patched.bas
+ ${BAS_TO_TOK} <$< >$@
+
+ribbit_patched.bas: ribbit.bas ribbit.bas.patch
+ cp ribbit.bas $@
+ patch $@ <ribbit.bas.patch
+
+ribbit.bas: ribbit.tok
+ ${TOK_TO_BAS} <$< >$@
+
+ribbit.tok: ribbit.bin
+ ${BIN_TO_TOK} <$< >$@
+
+ribbit.bin: ../orig/DOS_Tool_Kit_v1.0_1980_Apple.do
+ ${DOS33} $< LOAD RIBBIT $@
+
+tone.obj: \
+tone.asm \
+tone_asm.txt \
+bootable.dsk \
+../orig/DOS_Tool_Kit_v1.0_1980_Apple.do
+ cp ../orig/DOS_Tool_Kit_v1.0_1980_Apple.do .
+ tr '\t\na-z' ' \rA-Z' <tone.asm |\
+LC_ALL=C tr '\000-\177' '\200-\377' >__temp__.asm
+ ${MKDOS33FS} __temp__.dsk
+ ${DOS33} __temp__.dsk SAVE T __temp__.asm TONE.ASM
+ rm -f ../linapple-pie/Printer.txt
+ tr '\n' '\r' <tone_asm.txt |\
+( \
+ cd ../linapple-pie && \
+ ./linapple -b -1 ../ribbit/DOS_Tool_Kit_v1.0_1980_Apple.do -2 ../ribbit/__temp__.dsk \
+)
+ tr -d '\r' <../linapple-pie/Printer.txt >tone.lst
+ ${DOS33} __temp__.dsk LOAD TONE.OBJ $@
+ rm DOS_Tool_Kit_v1.0_1980_Apple.do __temp__.asm __temp__.dsk
+
+ribbit_tone.obj: \
+ribbit_tone.asm \
+ribbit_tone_asm.txt \
+bootable.dsk \
+../orig/DOS_Tool_Kit_v1.0_1980_Apple.do
+ cp ../orig/DOS_Tool_Kit_v1.0_1980_Apple.do .
+ tr '\t\na-z' ' \rA-Z' <ribbit_tone.asm |\
+LC_ALL=C tr '\000-\177' '\200-\377' >__temp__.asm
+ ${MKDOS33FS} __temp__.dsk
+ ${DOS33} __temp__.dsk SAVE T __temp__.asm "RIBBIT TONE.ASM"
+ rm -f ../linapple-pie/Printer.txt
+ tr '\n' '\r' <ribbit_tone_asm.txt |\
+( \
+ cd ../linapple-pie && \
+ ./linapple -b -1 ../ribbit/DOS_Tool_Kit_v1.0_1980_Apple.do -2 ../ribbit/__temp__.dsk \
+)
+ tr -d '\r' <../linapple-pie/Printer.txt >ribbit_tone.lst
+ ${DOS33} __temp__.dsk LOAD "RIBBIT TONE.OBJ" $@
+ rm DOS_Tool_Kit_v1.0_1980_Apple.do __temp__.asm __temp__.dsk
+
+ribbit_tone.asm: \
+ribbit_tone_disasm.txt \
+ribbit_tone_disasm.sed \
+bootable.dsk \
+../orig/DOS_Tool_Kit_v1.0_1980_Apple.do
+ rm -f ../linapple-pie/Printer.txt
+ tr '\n' '\r' <ribbit_tone_disasm.txt |\
+( \
+ cd ../linapple-pie && \
+ ./linapple -b -1 ../ribbit/bootable.dsk -2 ../orig/DOS_Tool_Kit_v1.0_1980_Apple.do \
+)
+ tr -d '\r' <../linapple-pie/Printer.txt |\
+sed -nf ribbit_tone_disasm.sed >__temp__.asm
+ sed -ne 's/^\(l\.[0-9a-f]\+\).*/\1/p' <__temp__.asm >__defs__.txt
+ sed -ne 's/^.\+\(l\.[0-9a-f]\+\).*/\1/p' <__temp__.asm >__refs__.txt
+ for i in `cat __defs__.txt`; \
+do \
+ if ! grep -q $$i __refs__.txt; \
+ then \
+ sed -e "s/$$i//" -i __temp__.asm; \
+ fi; \
+done
+ ( \
+ for i in `LC_ALL=C sort <__refs__.txt |uniq`; \
+ do \
+ if ! grep -q $$i __defs__.txt; \
+ then \
+ echo $$i; \
+ fi; \
+ done |sed -e 's/^l.\(.*\)/&\tequ\t$$\1/'; \
+ cat __temp__.asm; \
+) >$@
+ rm __temp__.asm __defs__.txt __refs__.txt
+
+bootable.dsk: ../orig/Apple_DOS_v3.3_1980_Apple.do bootable.txt
+ dd if=/dev/zero of=$@ count=35 bs=4096
+ tr '\n' '\r' <../ribbit/bootable.txt |\
+( \
+ cd ../linapple-pie && \
+ ./linapple -b -1 ../orig/Apple_DOS_v3.3_1980_Apple.do -2 ../ribbit/$@ \
+)
+
+clean:
+ rm -f \
+ribbit_patched.dsk \
+ribbit_patched.bin \
+ribbit_patched.tok \
+ribbit_patched.bas \
+ribbit.bas \
+ribbit.tok \
+ribbit.bin \
+bootable.dsk \
+__temp__.asm \
+__temp__.dsk \
+__defs__.txt \
+__refs__.txt
--- /dev/null
+NEW
+10 HOME
+20 PRINT "HELLO"
+INIT HELLO,D2
--- /dev/null
+BRUN EDASM.OBJ
+PR#1
+DR 2
+ASM RIBBIT TONE.ASM,RIBBIT TONE.OBJ
+
--- /dev/null
+/^0302-/,/^031C-/{
+ y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+ s/^\([^ ]\{4\}\)- \([^ ]\{2\}\( [^ ]\{2\}\)*\) \+\([^ ]\{3\}\) \(.*\)/l.\1\t\4\t\5\t\t\t\2/
+ s/\$/l./
+ s/#l\./#$/
+ s/\(,[xy]\)\t/\1/
+ s/^l.0302/\torg\t$0302\n&/
+ p
+}
--- /dev/null
+LOAD RIBBIT,D2
+10950 RETURN
+GOSUB 10900
+PR#1
+CALL -151
+302L
--- /dev/null
+spkr equ $c030
+ org $300
+rest lda #0
+ sta freql
+ sta freqh
+tone ldx #0
+durl equ *-1
+ ldy #0
+durh equ *-1
+loop lda #0
+freql equ *-1
+ adc #0
+countl equ *-1
+ sta countl
+ lda #0
+freqh equ *-1
+ adc #0
+counth equ *-1
+ sta counth
+ bcc nospkr
+ lda spkr
+nospkr inx
+ bne loop
+ iny
+ bne loop
+ rts
--- /dev/null
+BRUN EDASM.OBJ
+PR#1
+DR 2
+ASM TONE.ASM,TONE.OBJ
+