added the TI-74 BASIC port and the mu808asm'MU74 export support
This commit is contained in:
@@ -303,7 +303,10 @@ Reference implementations
|
||||
* [Python 3](mu808asm.py): supports assembling MU8A source files into both
|
||||
plain text (MU8) and binary (MU8B) machine code formats. Also supports
|
||||
disassembling MU8 and MU8B files into their MU8A sources and converting
|
||||
machine code between MU8 and MU8B formats.
|
||||
machine code between MU8 and MU8B formats. Additionally, this assembler
|
||||
implementation provides the `t74` mode to convert plaintext MU8 machine code
|
||||
into the format suitable for entering into TI-74 BASIC for running on the
|
||||
TI-74 port of mu808 (see below).
|
||||
|
||||
These lists are going to be expanded as soon as new reference implementations
|
||||
appear.
|
||||
@@ -331,6 +334,59 @@ keys of the standard phone keypad, the following convention is recommended:
|
||||
* the `#` (pound) key actually confirms entering a single number field, and
|
||||
all instructions are required to contain exactly five numbers.
|
||||
|
||||
Retro/minimal platform implementations
|
||||
--------------------------------------
|
||||
Here's the list of known/existing mu808 implementations that adhere to the
|
||||
specification to most extent and run compatible machine code but cannot
|
||||
provide full operating environment functionality due to the limits of the
|
||||
platform itself.
|
||||
|
||||
### TI-74 BASIC
|
||||
|
||||
The [mu808.b74](mu808.b74) file contains a BASIC port of mu808 for the Texas
|
||||
Instruments TI-74 portable computer (tested on the TI-74S variant). Due to
|
||||
the resource constraints, the following limitations apply:
|
||||
|
||||
* only 149 program steps and 256 data cells supported (adjustable at line 110),
|
||||
* no interactive mode (the `RUN` command directly executes the predefined
|
||||
program in the VM),
|
||||
* the program itself is entered into the DATA statements in the so-called
|
||||
MU74 format (see below),
|
||||
* no support for I/O port 2, tracing or intruction dumping,
|
||||
* no boundary checks for the addresses inside the program.
|
||||
|
||||
Also, since the VM runs on top of a BASIC interpreter, program execution is
|
||||
extremely slow most of the time. Keep in mind, this is more of a proof of
|
||||
concept than a viable solution, and using the "native" TI BASIC is preferred
|
||||
for any serious computing on that machine.
|
||||
|
||||
In order to store your programs on the device to run via this mu808 VM version,
|
||||
you need to enter them in DATA statements in two-number pairs starting from
|
||||
`DATA 0,0` at the BASIC line 5000. The last `DATA` line of the program must be
|
||||
`DATA -1,0`. In between these two, every program instruction `lno cmd a1 a2 a3`
|
||||
must be compressed into the form:
|
||||
```
|
||||
[5000+lno] DATA [cmd*10000 + a1], [a2 * 10000 + a3]
|
||||
```
|
||||
This storage format is called MU74. For example, the compound interest
|
||||
calculator from the official mu808 examples will transform into:
|
||||
```
|
||||
5000 DATA 0,0
|
||||
5001 DATA 50100,1
|
||||
5002 DATA 40002,30000
|
||||
5003 DATA 90002,10004
|
||||
5004 DATA 50001,5
|
||||
5005 DATA 70005,40005
|
||||
5006 DATA 130001,50005
|
||||
5007 DATA 70000,30005
|
||||
5008 DATA 130000,50005
|
||||
5009 DATA 30005,50000
|
||||
5010 DATA -1,0
|
||||
```
|
||||
To make the conversion easier, the official mu808 assembler, `mu808asm.py`, now
|
||||
supports the `t74` mode that accepts a plain MU8 machine code file and outputs
|
||||
the same program in the MU74 format.
|
||||
|
||||
FAQ
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
100 RANDOMIZE:RAD
|
||||
110 DIM PMEM(300),DMEM(256)
|
||||
120 RESTORE 5000
|
||||
130 I=0
|
||||
140 READ PMEM(I), PMEM(I+1)
|
||||
150 I=I+2
|
||||
160 IF PMEM(I-2)>-1 THEN 140
|
||||
170 L=1:IAT,V1,V2,V3=0
|
||||
180 M=L+L:A=PMEM(M):B=PMEM(M+1)
|
||||
190 IF A<0 THEN 730
|
||||
200 CMD=INT(A/10000)
|
||||
210 IF IAT=1 THEN 220 ELSE 230
|
||||
220 X=INT(V1):Y=INT(V2):Z=INT(V3):IAT=0:GOTO 240
|
||||
230 X=A-CMD*10000:Y=INT(B/10000):Z=B-Y*10000
|
||||
240 V1,V2,V3=0
|
||||
250 IF CMD=5 THEN DMEM(Z)=X+(Y/10000):GOTO 720
|
||||
260 V1=DMEM(X):V2=DMEM(Y):V3=DMEM(Z)
|
||||
270 IF CMD=1 THEN 280 ELSE 420
|
||||
280 IF X=0 AND V2=0 THEN L=Z-1:GOTO 720
|
||||
290 IF X=1 AND V2>0 THEN L=Z-1:GOTO 720
|
||||
300 IF X=2 AND V2<0 THEN L=Z-1:GOTO 720
|
||||
310 IF X=3 AND V2>=0 THEN L=Z-1:GOTO 720
|
||||
320 IF X=4 AND V2<=0 THEN L=Z-1:GOTO 720
|
||||
330 IF X=5 AND V2<>0 THEN L=Z-1:GOTO 720
|
||||
340 IF X=6 THEN L=Z-1:GOTO 720
|
||||
350 IF X=7 AND V2=0 THEN L=INT(V3)-1:GOTO 720
|
||||
360 IF X=8 AND V2>0 THEN L=INT(V3)-1:GOTO 720
|
||||
370 IF X=9 AND V2<0 THEN L=INT(V3)-1:GOTO 720
|
||||
380 IF X=10 AND V2>=0 THEN L=INT(V3)-1:GOTO 720
|
||||
390 IF X=11 AND V2<=0 THEN L=INT(V3)-1:GOTO 720
|
||||
400 IF X=12 AND V2<>0 THEN L=INT(V3)-1:GOTO 720
|
||||
410 IF X=13 THEN L=INT(V3)-1:GOTO 720
|
||||
420 IF CMD=2 THEN IAT=1:GOTO 720
|
||||
430 IF CMD=3 THEN 440 ELSE 490
|
||||
440 FOR I=X TO Y
|
||||
450 IF Z=0 THEN PRINT(DMEM(I)):PAUSE
|
||||
460 IF Z=1 THEN 470 ELSE 480
|
||||
470 IF DMEM(I)=10 THEN PAUSE ELSE PRINT(CHR$(INT(DMEM(I))));
|
||||
480 NEXT I:GOTO 720
|
||||
490 IF CMD=4 THEN 500 ELSE 530
|
||||
500 FOR I=X TO Y
|
||||
510 IF Z=0 THEN INPUT DMEM(I)
|
||||
520 NEXT I:GOTO 720
|
||||
530 IF CMD=6 THEN 540 ELSE 570
|
||||
540 IF X=0 THEN DMEM(Z)=Y:GOTO 720
|
||||
550 IF X=1 THEN DMEM(Z)=V2:GOTO 720
|
||||
560 IF X>1 THEN DMEM(INT(V3))=DMEM(INT(V2)):GOTO 720
|
||||
570 IF CMD=7 THEN DMEM(Z)=V1+V2*V3:GOTO 720
|
||||
580 IF CMD=8 THEN DMEM(Z)=V1-V2:GOTO 720
|
||||
590 IF CMD=9 THEN 600 ELSE 610
|
||||
600 IF V2=0 THEN DMEM(Z)=0:GOTO 720 ELSE DMEM(Z)=V1/V2:GOTO 720
|
||||
610 IF CMD=10 THEN 620 ELSE 630
|
||||
620 IF V2=0 THEN DMEM(Z)=INT(V1):GOTO 720 ELSE DMEM(Z)=V1-V2*INT(V1/V2):GOTO 720
|
||||
630 IF CMD=11 THEN DMEM(Z)=ABS(V2):GOTO 720
|
||||
640 IF CMD=12 THEN DMEM(Z)=SQR(ABS(V2)):GOTO 720
|
||||
650 IF CMD=13 THEN 660 ELSE 670
|
||||
660 IF X=0 THEN DMEM(Z)=EXP(V2):GOTO 720 ELSE DMEM(Z)=LN(ABS(V2)):GOTO 720
|
||||
670 IF CMD=14 THEN 680 ELSE 710
|
||||
680 IF X=0 THEN DMEM(Z)=SIN(V2):GOTO 720
|
||||
690 IF X=1 THEN DMEM(Z)=COS(V2):GOTO 720
|
||||
700 IF X>1 THEN DMEM(Z)=ATN(V2):GOTO 720
|
||||
710 IF CMD=15 THEN DMEM(Z)=INT(V1)+INT(RND*(INT(V2)-INT(V1)+1))
|
||||
720 L=L+1:GOTO 180
|
||||
730 END
|
||||
+31
-1
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
# a simple assembler/disassembler for the mu808 VM
|
||||
# supports both text and binary program formats
|
||||
# usage: mu808asm [at|ab|dt|db|t2b|b2t] file outfile
|
||||
# usage: mu808asm [at|ab|dt|db|t2b|b2t|t74] file outfile
|
||||
# modes:
|
||||
# at: assemble to plaintext (MU8) machine code
|
||||
# ab: assemble to binary (MU8B) machine code
|
||||
@@ -9,6 +9,7 @@
|
||||
# db: disassemble binary (MU8B) machine code
|
||||
# t2b: convert from plaintext MU8 to binary MU8B
|
||||
# b2t: convert from binary MU8B to plaintext MU8
|
||||
# t74: convert from plaintext MU8 to the TI-74 representation
|
||||
|
||||
import sys, re, struct
|
||||
|
||||
@@ -132,6 +133,33 @@ def totext(binrep):
|
||||
out += ' '.join([str(lno), str(cmd), str(x), str(y), str(z)]) + '\n'
|
||||
return out
|
||||
|
||||
# converts the MU8 plaintext machine code to the TI-74 DATA statements (MU74)
|
||||
def ti74data(txtrep:str, baseaddr:int=5000):
|
||||
instrs = [] # instruction list to store here
|
||||
vreg = re.compile(r'\s+')
|
||||
iindex = 0
|
||||
instr = []
|
||||
for instrpart in vreg.split(txtrep):
|
||||
if iindex == 5:
|
||||
instrs.append(instr)
|
||||
instr = []
|
||||
iindex = 0
|
||||
if len(instrpart) > 0:
|
||||
instr.append(int(instrpart))
|
||||
iindex += 1
|
||||
# now, instrs contains 5-number groups
|
||||
out = f'{baseaddr} DATA 0,0\n'
|
||||
maxlno = 0
|
||||
for instr in instrs:
|
||||
lno, cmd, x, y, z = instr
|
||||
if lno > maxlno:
|
||||
maxlno = lno
|
||||
a = cmd*10000 + x
|
||||
b = y*10000 + z
|
||||
out += f'{baseaddr + lno} DATA {a},{b}\n'
|
||||
out += f'{baseaddr + maxlno + 1} DATA -1,0\n'
|
||||
return out
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 4:
|
||||
print("Usage: mu808asm [at|ab|dt|db|t2b|b2t] file outfile")
|
||||
@@ -162,6 +190,8 @@ def main():
|
||||
elif mode == 'db': # disassemble binary
|
||||
srctext = totext(srctext)
|
||||
output = disassemble(srctext)
|
||||
elif mode == 't74': # convert to TI-74 DATA statements
|
||||
output = ti74data(srctext)
|
||||
else: # assemble
|
||||
output = assemble(srctext) # default mode
|
||||
if mode == 'ab':
|
||||
|
||||
Reference in New Issue
Block a user