東大版2K Tiny BASICの文法メモと移植版ソースを相当な年数を経て発掘したので無くさないようにクラウド化する。Windows95華やかりし頃に作成して以来メンテしていないから内容についての保証はいたしかねる。
Tiny BASIC関連の記事を久しぶりにメンテした関連。東大版2K Tiny BASICも元はPALO ALTO TINY BASICだったはずなので次の記事の文法解説としてはこれで間に合う。Win32でも動く東大版ではないオリジナルのPALO ALTO TYNY BASICコードは次のエントリで掲載。
8080のTinyBASICで遊ぶ その1
https://mzex.wordpress.com/2018/05/26/12977/
※例によって半角の山カッコはWordpressで破壊されるので全角の<>に置換。
Tiny BASIC文法メモ
*コマンド NEW LIST <値> RUN *ステートメント LET <変数>=<式> ※LET は省略可 PRINT [<リテラル>,式] INPUT [<リテラル>],変数] GOTO <式> GOSUB <式> RETURN IF <式> <ステートメント|コマンド> FOR <変数>=<式> TO <式> [STEP <式>] ~ NEXT <変数> STOP SYSTEM ※CP/Mに戻る、ウォームリブート。独自拡張。 マルチステートメントは ';' (<ステートメント>;<ステートメント>) *関数 RND(<式>) 1~<式>までの値を返す ABS(<式>) <式>の絶対値を返す SIZE 空きメモリのサイズを返す *演算子 = 等しい # 等しくない > より大きい >= 以上 < 未満 <= 以下 + 加算 または 正 - 減算 または 負 * 乗算 / 除算 *変数 A-Z 単純変数 (一文字のみ) @(<式>) 配列変数 (空きメモリの範囲) *整数 -32768~32767 (10進)
Z-80版のTiny BASICも発掘されたので同時にクラウド化しておく。アスキー1977年8月号の東大版TinyBASICを秋月電子扱いでお安いシステムロード社製のアブソリュートクロスアセンブラXA80 Ver2.01でアセンブルできように移植して、CP/Mのトランジェントコマンドとしても実行できるようにしたもの。アスキー1977年10月号のバグフィックスパッチも適用済み。RAM領域は秋月電子のAKI-80に合わせて8000Hから始まるようにしたので本物のCP/Mだと定義を変更しない場合はRAM48kB以上実装のシステムが必要。実際はシステムロードのCP/M-Simulator Ver.3.21とAKI-80の自作ROM-BIOS上のみで確認しているので実機は未確認。例によって半角の山カッコはWordpressで破壊されるので全角の<>に置換。
[TBCPM.ASM]
; ; ; PALO ALTO TINY BASIC ; ; ; FOR Z-80 CP/M VERSION ; STACK EQU 0E400H VTOP EQU 0E000H LBUF EQU 0E337H MSTK EQU 0E3A7H RAMST EQU 08000H IENT EQU 0100H IFLG EQU 0FBH OFLG EQU 0FBH OCNT EQU 0FBH ITTY EQU 0FAH OTTY EQU 0FAH IMSK EQU 002H OMSK EQU 001H ;TST MACRO STR,ADRS ; CALL TEST ; DB STR ; DB ADRS-$-1 ; ENDM ;CASE MACRO STR,ADRS ; DB STR ; DB (ADRS+8000H) SHR 8 ; DB ADRS AND 0FFH ; ENDM ;ENDC MACRO ADRS ; DB (ADRS+8000H) SHR 8 ; DB ADRS AND 0FFH ; ENDM ORG IENT CALL STRUP ;INITIALIZE START: ; DI ;START LD SP,STACK JP ENTRY ; TEST: EX (SP),HL ;TEST CHARACTER CALL SKPBL CP (HL) JP TEST1 ; CRLF: LD A,0DH PUT: PUSH AF ;PUT CHARACTER IN A REG JP TTYO1 ; EEXPR: CALL EXPR ;EXTENDED EXPRESSION PUSH HL JP RST31 ; COMPR: LD A,H ;COMPARE DE AND HL CP D RET NZ LD A,L CP E RET ; SKPBL: LD A,(DE) ;SKIP BLANK CP ' ' RET NZ INC DE JP SKPBL ; ENDL: CALL TSTSC ;TEST LINE END JP LERMS ; TSTV: CALL SKPBL ;TEST VARIABLE SUB 40H RET C JP NZ,TSTV1 INC DE CALL EXPR0 ADD HL,HL JP C,ERROR PUSH DE EX DE,HL CALL RSIZE CALL COMPR JP C,SYSO1 LD HL,VTOP CALL DIFF POP DE RET ; TSTV1: CP 1BH ;'A' 'Z' ? CCF RET C ;NO INC DE LD HL,VTOP RLCA ADD A,L LD L,A LD A,00H ADC A,H LD H,A RET ; TEST1: INC HL JP Z,TSTEQ PUSH BC LD C,(HL) ;FETCH SKIP NUMBER LD B,00H ADD HL,BC POP BC DEC DE TSTEQ: INC DE INC HL EX (SP),HL RET ; GINT: LD HL,0000H ;GET INTEGER LD B,H CALL SKPBL GETI1: CP 30H RET C ;RETURN INTEGER IN HL CP 3AH RET NC LD A,0F0H AND H ;IF INTEGER>#0FFF ERROR JP NZ,ERROR INC B PUSH BC LD B,H ;HL HL+10 LD C,L ADD HL,HL ADD HL,HL ADD HL,BC ADD HL,HL LD A,(DE) ;HL HL+(DE)�F INC DE AND 0FH ADD A,L LD L,A LD A,00H ADC A,H LD H,A POP BC LD A,(DE) JP P,GETI1 ; ERROR: PUSH DE ERR1: LD DE,HOWMS JP LEMS1 ; HOWMS: DB 'HOW?' DB 0DH OKMES: DB 'OK' DB 0DH WHTMS: DB 'WHAT?' DB 0DH SRYMS: DB 'SORRY' DB 0DH ; ENTRY: CALL CRLF LD DE,OKMES SUB A CALL MSG LD HL,00CBH LD (COBJ),HL LD HL,0000H LD (FCNTR),HL LD (RSTCK),HL ; GETC: LD A,'>' ;'>' PROMPT CALL GETL PUSH DE ;SAVE LINE END LD DE,LBUF CALL GINT ;HL=LABEL NUMBER CALL SKPBL LD A,H OR L POP BC ;RECOVER LINE END JP Z,KWCPR ;IF LABEL NUMBER=0 COMMAND INSRT: DEC DE LD A,H LD (DE),A DEC DE LD A,L LD (DE),A PUSH BC ;SAVE LINE BOTTOM PUSH DE ;SAVE LINE TOP LD A,C SUB E PUSH AF ;SAVE LINE LENGTH CALL SRCH PUSH DE ;SAVE CURRENT LINE JP NZ,MOVE PUSH DE ;EXIST SAME LINE CALL SKIPL POP BC LD HL,(OBTM) CALL TRNSF ;ERASE OLD LINE LD H,B LD L,C LD (OBTM),HL ;UPDATE BOTTOM POINTER MOVE: POP BC ;RECOVER CURRENT LINE LD HL,(OBTM) POP AF ;RECOVER LINE LENGTH PUSH HL ;SAVE CURRENT BOTTOM CP 03H JP Z,START ;LENGTH=3? RESTART ADD A,L ;COMPUTE MOVE BOTTOM LD L,A LD A,00H ADC A,H LD H,A LD DE,VTOP CALL COMPR JP NC,SYSOF LD (OBTM),HL POP DE ;RECOVER CURRENT BOTTOM CALL TR2 ;MOVE FOR INSERTION POP DE ;RECOVER LINE TOP POP HL ;RECOVER LINE BOTTOM CALL TRNSF ;INSERT LINE JP GETC ; CMDKW: ; CASE '''LIST''',LIST DB 'LIST' DB (LIST+8000H) SHR 8 DB LIST AND 0FFH ; CASE '''RUN''',RUN DB 'RUN' DB (RUN+8000H) SHR 8 DB RUN AND 0FFH ; CASE '''NEW''',NEW DB 'NEW' DB (NEW+8000H) SHR 8 DB NEW AND 0FFH ; CASE '''SYSTEM''',SYSTM DB 'SYSTEM' DB (SYSTM+8000H) SHR 8 DB SYSTM AND 0FFH STMKW: ; CASE '''NEXT''',NEXT DB 'NEXT' DB (NEXT+8000H) SHR 8 DB NEXT AND 0FFH ; CASE '''LET''',LET DB 'LET' DB (LET+8000H) SHR 8 DB LET AND 0FFH ; CASE '''IF''',IFSTM DB 'IF' DB (IFSTM+8000H) SHR 8 DB IFSTM AND 0FFH ; CASE '''GOTO''',GOTO DB 'GOTO' DB (GOTO+8000H) SHR 8 DB GOTO AND 0FFH ; CASE '''GOSUB''',GOSUB DB 'GOSUB' DB (GOSUB+8000H) SHR 8 DB GOSUB AND 0FFH ; CASE '''RETURN''',RETRN DB 'RETURN' DB (RETRN+8000H) SHR 8 DB RETRN AND 0FFH ; CASE '''REM''',REM DB 'REM' DB (REM+8000H) SHR 8 DB REM AND 0FFH ; CASE '''FOR''',FOR DB 'FOR' DB (FOR+8000H) SHR 8 DB FOR AND 0FFH ; CASE '''INPUT''',INPUT DB 'INPUT' DB (INPUT+8000H) SHR 8 DB INPUT AND 0FFH ; CASE '''PRINT''',PRINT DB 'PRINT' DB (PRINT+8000H) SHR 8 DB PRINT AND 0FFH ; CASE '''STOP''',STOP DB 'STOP' DB (STOP+8000H) SHR 8 DB STOP AND 0FFH ; ENDC CMDER DB (CMDER+8000H) SHR 8 DB CMDER AND 0FFH FNKW: ; CASE '''RND''',RND DB 'RND' DB (RND+8000H) SHR 8 DB RND AND 0FFH ; CASE '''ABS''',FNABS DB 'ABS' DB (FNABS+8000H) SHR 8 DB FNABS AND 0FFH ; CASE '''SIZE''',RSIZE DB 'SIZE' DB (RSIZE+8000H) SHR 8 DB RSIZE AND 0FFH ; ENDC FACT2 DB (FACT2+8000H) SHR 8 DB FACT2 AND 0FFH KWTO: ; CASE '''TO''',FORTO DB 'TO' DB (FORTO+8000H) SHR 8 DB FORTO AND 0FFH ; ENDC LERMS DB (LERMS+8000H) SHR 8 DB LERMS AND 0FFH KWSTP: ; CASE '''STEP''',STEP DB 'STEP' DB (FSTEP+8000H) SHR 8 DB FSTEP AND 0FFH ; ENDC FSTP1 DB (FSTP1+8000H) SHR 8 DB FSTP1 AND 0FFH ROPKW: ; CASE '''>=''',LGE DB '>=' DB (LGE+8000H) SHR 8 DB LGE AND 0FFH ; CASE '''#''',LNE DB '#' DB (LNE+8000H) SHR 8 DB LNE AND 0FFH ; CASE '''>''',LGT DB '>' DB (LGT+8000H) SHR 8 DB LGT AND 0FFH ; CASE '''=''',LEQ DB '=' DB (LEQ+8000H) SHR 8 DB LEQ AND 0FFH ; CASE '''<=''',LLE DB '<=,' DB (LLE+8000H) SHR 8 DB LLE AND 0FFH ; CASE '''<''',LLT DB '<' DB (LLT+8000H) SHR 8 DB LLT AND 0FFH ; ENDC NOROP DB (NOROP+8000H) SHR 8 DB NOROP AND 0FFH ; KWCPR: LD HL,CMDKW-1 NXTKW: CALL SKPBL PUSH DE ;SAVE LINE TOP KWC1: LD A,(DE) INC DE CP 2EH ;'.' JP Z,KWSRT INC HL CP (HL) JP Z,KWC1 LD A,7FH DEC DE CP (HL) JP C,EXEQT ;WHOLE KEYWORD? KWSK1: INC HL CP (HL) JP NC,KWSK1 INC HL POP DE ;RECOVER LINE TOP JP NXTKW ; KWSRT: LD A,7FH KWSK2: INC HL CP (HL) JP NC,KWSK2 ; EXEQT: LD A,(HL) ;FTECH EXEC ADDR HIGH INC HL LD L,(HL) ;FETCH EXEC ADDR LOW AND 7FH LD H,A POP AF ;DUMMY POP UP JP (HL) ;GOTO EACH ROUTINE ; SYSTM: CALL MONBK JP IFST2 ; NEW: CALL TSCR2 LD HL,OTOP LD (OBTM),HL STOP: CALL TSCR2 JP START ; RUN: CALL TSCR2 LD DE,OTOP ; RUN1: LD HL,0000H CALL SRCH1 ;SEARCH MINIMUM LABEL OR JP C,START ; RUN2: EX DE,HL LD (COBJ),HL EX DE,HL INC DE ;SKIP LABEL INC DE ; NXTGO: CALL BREAK LD HL,STMKW-1 JP NXTKW ; GOTO: CALL EEXPR PUSH DE ;SAVE LINE POINTER CALL TSCR2 CALL SRCH JP NZ,ERR1 POP AF ;DUMMY POP JP RUN2 ; LIST: CALL GINT CALL TSCR2 CALL SRCH LISTL: JP C,START ;IF EMPTY OR EOF RESTART CALL WLINE CALL BREAK CALL SRCH1 JP LISTL ; PRINT: LD C,06H ; ; TST ''';''',PRNT1 CALL TEST DB ';' DB PRNT1-$-1 CALL CRLF JP NXTGO ; PRNT1: ; TST 0DH,PRNT2 CALL TEST DB 0DH DB PRNT2-$-1 CALL CRLF JP RUN1 ; PRNT2: ; TST '''#''',PRNT3 CALL TEST DB '#' DB PRNT3-$-1 CALL EEXPR LD C,L JP PRNT4 PRNT3: CALL PR10 JP PRNT6 PRNT4: ; TST ''',''',PRNT5 CALL TEST DB ',' DB PRNT5-$-1 CALL TSTSC JP PRNT2 ; PRNT5: CALL CRLF JP ENDL ; PRNT6: CALL EEXPR PUSH BC CALL WINT POP BC JP PRNT4 ; GOSUB: CALL PSHV CALL EEXPR PUSH DE ;SAVE OBJ POINTER CALL SRCH JP NZ,ERR1 LD HL,(COBJ) PUSH HL LD HL,(RSTCK) PUSH HL LD HL,0000H LD (FCNTR),HL ADD HL,SP LD (RSTCK),HL JP RUN2 ; RETRN: CALL TSCR2 LD HL,(RSTCK) LD A,H OR L JP Z,LERMS ;IF RSTACKTOP=0 ERROR LD SP,HL POP HL LD (RSTCK),HL POP HL LD (COBJ),HL POP DE CALL POPV JP ENDL ; FOR: CALL PSHV CALL LTSUB DEC HL LD (FCNTR),HL LD HL,KWTO-1 JP NXTKW ; FORTO: CALL EEXPR LD (FTOV),HL LD HL,KWSTP-1 JP NXTKW ; FSTEP: CALL EEXPR JP FOR0 ; FSTP1: LD HL,0001H FOR0: LD (FSTPV),HL LD HL,(COBJ) LD (FLABL),HL EX DE,HL LD (FOBJ),HL LD BC,000AH LD HL,(FCNTR) EX DE,HL LD H,B LD L,B ADD HL,SP DB 3EH ;(SKIP NEXT INSTRUCTION) ; FOR3: ADD HL,BC LD A,(HL) INC HL OR (HL) JP Z,FOR10 LD A,(HL) DEC HL CP D JP NZ,FOR3 LD A,(HL) CP E JP NZ,FOR3 EX DE,HL LD HL,0000H ADD HL,SP LD B,H LD C,L LD HL,000AH ADD HL,DE CALL TR2 LD SP,HL FOR10: LD HL,(FOBJ) EX DE,HL JP ENDL ; NEXT: CALL TSTV JP C,LERMS LD (NCNTR),HL NEXT1: PUSH DE EX DE,HL LD HL,(FCNTR) LD A,H OR L JP Z,LEMS0 CALL COMPR JP Z,NEXT2 ;NEXT VAR.=FORVAR.? POP DE CALL POPV LD HL,(NCNTR) JP NEXT1 NEXT2: LD E,(HL) INC HL LD D,(HL) ;DE OLD FOR VALUE LD HL,(FSTPV) PUSH HL ;HL STEP VALUE ADD HL,DE EX DE,HL ;DE NEW FOR VALUE LD HL,(FCNTR) LD (HL),E INC HL LD (HL),D ;FOR VAR. NEW VALUE LD HL,(FTOV) POP AF OR A JP P,NEXT4 EX DE,HL NEXT4: CALL CMINT POP DE JP C,NEXT5 LD HL,(FLABL) LD (COBJ),HL LD HL,(FOBJ) EX DE,HL JP ENDL ; NEXT5: CALL POPV JP ENDL ; REM: LD HL,0000H JP IFST2 ; IFSTM: CALL EEXPR LD A,H OR L JP NZ,NXTGO IFST2: CALL SKPL2 JP NC,RUN2 JP START ; ERRIN: LD HL,(NCNTR) LD SP,HL POP HL LD (COBJ),HL POP DE POP DE INPUT: PUSH DE CALL PR10 JP INPT2 ; INPT1: CALL TSTV JP C,INPT6 JP INPT4 INPT2: PUSH DE CALL TSTV JP C,LERMS LD A,(DE) LD C,A SUB A LD (DE),A POP DE CALL MSG LD A,C DEC DE LD (DE),A ; INPT4: PUSH DE EX DE,HL LD HL,(COBJ) PUSH HL LD HL,INPUT LD (COBJ),HL LD HL,0000H ADD HL,SP LD (NCNTR),HL PUSH DE LD A,':' CALL GETL LD DE,LBUF CALL EEXPR POP DE EX DE,HL LD (HL),E INC HL LD (HL),D POP HL LD (COBJ),HL POP DE ; INPT6: POP AF ; TST ''',''',LTEND CALL TEST DB ',' DB LTEND-$-1 JP INPUT ; CMDER: LD A,(DE) CP 0DH JP Z,ENDL ; LET: CALL LTSUB ; TST ''',''',LTEND CALL TEST DB ',' DB LTEND-$-1 JP LET LTEND: JP ENDL ; RST31: LD HL,ROPKW-1 JP NXTKW ; LGE: CALL IFEXQ RET C LD L,A RET ; LNE: CALL IFEXQ RET Z LD L,A RET ; LGT: CALL IFEXQ RET Z RET C LD L,A RET ; LLE: CALL IFEXQ LD L,A RET Z RET C LD L,H RET ; LEQ: CALL IFEXQ RET NZ LD L,A RET ; LLT: CALL IFEXQ RET NC LD L,A RET ; NOROP: POP HL RET ; IFEXQ: LD A,C ;SAVE C POP HL ;EXCHANGE STACK TOP 2 POP BC PUSH HL PUSH BC LD C,A ;RECOVER C CALL EXPR EX DE,HL ;EXCANGE LP AND 1 AND 2 EX (SP),HL CALL CMINT POP DE LD HL,0000H LD A,01H RET ;SET C AND Z FF ; EXPR: ; TST '''-''',EXPR1 CALL TEST DB '-' DB EXPR1-$-1 LD HL,0000H JP NEGA1 ; EXPR1: ; TST '''+''',EXPR3 CALL TEST DB '+' DB EXPR3-$-1 EXPR3: CALL TERM ; EXPR2: ; TST '''+''',NEGA0 CALL TEST DB '+' DB NEGA0-$-1 PUSH HL ;SAVE VALUE CALL TERM ADDDBL: EX DE,HL EX (SP),HL ;XCHANGE LP AND 1 AND 2 LD A,H XOR D LD A,D ADD HL,DE POP DE ;RECOVER LINE POINTER JP M,EXPR2 ;CHECK OVERFLOW XOR H JP P,EXPR2 JP ERROR ; NEGA0: ; TST '''-''',EXPRT CALL TEST DB '-' DB EXPRT-$-1 ; NEGA1: PUSH HL ;SAVE VALUE CALL TERM CALL TWSCP JP ADDDBL ; TERM: CALL FACTR ; MULT: ; TST '''*''',DIV CALL TEST DB '*' DB DIV-$-1 PUSH HL ;SAVE FACTOR VALUE CALL FACTR LD B,00H ;SET SIGN PUS CALL ABS EX DE,HL EX (SP),HL CALL ABS LD A,H OR A JP Z,MULT1 LD A,D OR D EX DE,HL JP NZ,ERR1 ;IF BOTH MULTIPLIER>#00FF MULT1: LD A,L LD HL,0000H OR A JP Z,TERM1 ;IF ONE OF MULTIPLIER=0 V MULTL: ADD HL,DE JP C,ERR1 ;OVERFLOW? DEC A JP NZ,MULTL JP TERM1 ; DIV: ; TST '''/''',EXPRT CALL TEST DB '/' DB EXPRT-$-1 PUSH HL ;SAVE VALUE CALL FACTR LD B,00H ;SET SIGN PLUS CALL ABS EX DE,HL EX (SP),HL CALL ABS LD A,D OR E JP Z,ERR1 ;ZERO DIV? PUSH BC ;SAVE SIGN CALL DIVID LD H,B LD L,C POP BC ;RECOVER SIGN TERM1: POP DE LD A,H OR A JP M,ERROR ;OVERFLOW? LD A,B OR A CALL M,TWSCP JP MULT ; FACTR: LD HL,FNKW-1 JP NXTKW ; FACT2: CALL TSTV ;FROM KEY WORD MISMATCH JP C,FNUM LD A,(HL) INC HL LD H,(HL) LD L,A RET ;RETURN VALUE ON HL ; FNUM: CALL GINT LD A,B OR A RET NZ ; EXPR0: ; TST '''(''',EXPER CALL TEST DB '(' DB EXPER-$-1 CALL EEXPR ; TST ''')''',EXPER CALL TEST DB ')' DB EXPER-$-1 EXPRT: RET EXPER: JP LERMS ; RND: CALL EXPR0 LD A,H OR A JP M,ERROR OR L JP Z,ERROR PUSH DE PUSH HL LD HL,(RWRK) LD A,H AND 07H LD H,A LD DE,IENT ADD HL,DE RND1: LD E,(HL) INC HL LD D,(HL) LD (RWRK),HL POP HL EX DE,HL PUSH BC CALL DIVID POP BC POP DE INC HL RET ; FNABS: CALL EXPR0 CALL ABS LD A,H OR H JP M,ERROR RET ; RSIZE: LD HL,(OBTM) ;VTOP-(CURRENTLB) PUSH DE EX DE,HL LD HL,VTOP CALL DIFF POP DE RET ; DIVID: PUSH HL LD L,H LD H,00H CALL DIVSB LD B,C LD A,L POP HL LD H,A DIVSB: LD C,0FFH DIVS1: INC C CALL DIFF JP NC,DIVS1 ADD HL,DE RET ; DIFF: LD A,L SUB E LD L,A LD A,H SBC A,D LD H,A RET ; ABS: LD A,H ;ABSOLUTE->HL SIGN->B OR A RET P TWSCP: LD A,H ;HL -HL CPL LD H,A LD A,L CPL LD L,A INC HL LD A,B ;SIGN EXCANGE XOR 80H LD B,A RET ; CMINT: LD A,H ;SIGN CHECK XOR D JP P,CPIN1 EX DE,HL CPIN1: CALL COMPR RET ; LTSUB: CALL TSTV JP C,LERMS PUSH HL ; TST '''=''',LTERR CALL TEST DB '=' DB LTERR-$-1 CALL EEXPR LD B,H LD C,L POP HL LD (HL),C INC HL LD (HL),B RET LTERR: JP LERMS ; TSTSC: ; TST ''';''',TSCR1 CALL TEST DB ';' DB TSCR1-$-1 POP AF JP NXTGO ; TSCR1: ; TST 0DH,TSRTN CALL TEST DB 0DH DB TSRTN-$-1 POP AF JP RUN1 TSRTN: RET ; TSCR2: CALL SKPBL CP 0DH RET Z ; LERMS: PUSH DE ;SAVE LINE POINTER LEMS0: LD DE,WHTMS LEMS1: SUB A CALL MSG POP DE ;RECOVER LINE POINTER LD A,(DE) PUSH AF SUB A LD (DE),A LD HL,(COBJ) PUSH HL LD A,(HL) INC HL OR (HL) POP DE JP Z,START LD A,(HL) OR A JP M,ERRIN CALL WLINE DEC DE POP AF LD (DE),A LD A,3FH ;'?' CALL PUT SUB A CALL MSG JP START ; SYSOF: PUSH DE SYSO1: LD DE,SRYMS JP LEMS1 ; GETL: CALL PUT LD DE,LBUF GETL1: CALL BREAK ;GET CHARACTER JP Z,GETL1 ; CALL PUT CP 0AH JP Z,GETL1 ;NEG. LF OR A JP Z,GETL1 ;NEG. NUL CP 7FH JP Z,RUB ;RUB? CP 7DH ; ? JP Z,CAN LD (DE),A ;STORE INTO LINE BUFFER INC DE CP 0DH ;CR? RET Z LD A,E ;BUF. FULL? CP 7FH JP NZ,GETL1 ; RUB: LD A,E ;BUF EMPTY? CP 37H JP Z,CAN DEC DE LD A,5CH ;"\" PRINT CALL PUT JP GETL1 ; CAN: CALL CRLF ;CANCEL LINE LD A,5EH JP GETL ; SRCH: LD A,H ;SEARCH CURRENT LINE POSI OR A ;HL=INPUT LABEL NO JP M,ERROR LD DE,OTOP SRCH1: PUSH HL LD HL,(OBTM) DEC HL CALL COMPR ;COMPARE OBJ BOTTOM TO OB POP HL RET C LD A,(DE) ;COMPARE OBJ LABEL TO INP SUB L LD B,A INC DE LD A,(DE) SBC A,H JP C,SKPL1 ;IF < SKIP LINE DEC DE OR B RET ;RETURN GT(A<>0) EQ(A=0) ; SKIPL: INC DE SKPL1: INC DE SKPL2: LD A,(DE) CP 0DH JP NZ,SKPL1 ;SKIP UNTIL 'CR' INC DE JP SRCH1 ; MSG: LD B,A MSG1: LD A,(DE) INC DE CP B RET Z CALL PUT CP 0DH JP NZ,MSG1 RET ; PR10: ; TST '''"''',PR13 CALL TEST DB '"' DB PR13-$-1 LD A,22H PR11: CALL MSG CP 0DH POP HL JP Z,RUN1 PR12: INC HL INC HL INC HL JP (HL) ; PR13: ; TST '''''''''',PR14 CALL TEST DB "'" DB PR14-$-1 LD A,27H JP PR11 ; PR14: ; TST 5FH,PR15 CALL TEST DB 5FH DB PR15-$-1 LD A,8DH CALL PUT CALL PUT POP HL JP PR12 ; PR15: RET ; WINT: PUSH DE ;WRITE INTEGER LD DE,000AH PUSH DE LD B,D DEC C CALL ABS JP P,WINT1 LD B,2DH ;'-' DEC C WINT1: PUSH BC WINT2: CALL DIVID LD A,B OR C JP Z,WINT3 EX (SP),HL DEC L PUSH HL LD H,B LD L,C JP WINT2 WINT3: POP BC WINT4: DEC C LD A,C OR A JP M,WINT5 LD A,' ' CALL PUT JP WINT4 WINT5: LD A,B CALL PUT LD E,L WINT6: LD A,E CP 0AH POP DE RET Z ADD A,30H CALL PUT JP WINT6 ; WLINE: LD A,(DE) ;HL (DE),(DE+1) LD L,A INC DE LD A,(DE) LD H,A INC DE LD C,04H ;C=COLMN CALL WINT LD A,' ' CALL PUT SUB A CALL MSG RET ; TRNSF: CALL COMPR ;(BC) (DE) (HL-1) RET Z LD A,(DE) LD (BC),A INC DE INC BC JP TRNSF ; TR2: LD A,B ;(BC+1) (DE) (HL-1) SUB D JP NZ,TR2E LD A,C SUB E RET Z ;IF BC=DE RETURN TR2E: DEC DE DEC HL LD A,(DE) LD (HL),A JP TR2 ; POPV: POP BC POP HL LD (FCNTR),HL LD A,H OR L JP Z,NPOP POP HL LD (FSTPV),HL POP HL LD (FTOV),HL POP HL LD (FLABL),HL POP HL LD (FOBJ),HL NPOP: PUSH BC RET ; PSHV: LD HL,MSTK CALL TWSCP POP BC ADD HL,SP JP NC,SYSOF LD HL,(FCNTR) LD A,H OR L JP Z,NPSH LD HL,(FOBJ) PUSH HL LD HL,(FLABL) PUSH HL LD HL,(FTOV) PUSH HL LD HL,(FSTPV) PUSH HL LD HL,(FCNTR) NPSH: PUSH HL PUSH BC RET ; TTYO1: TTYO0: POP AF PUSH AF CALL PUTCH POP AF CP 0DH RET NZ LD A,0AH CALL PUT LD A,0DH RET ; BREAK: CALL KBHIT OR A ; RET NZ RET Z TTYI1: CALL GETCH AND 7FH CP 13H JP NZ,TTYI2 TTYI3: CALL GETCH CP 11H JP NZ,TTYI3 JP BREAK ; TTYI2: CP 03H RET NZ JP START ; MONBK: CALL EXIT RET ; ; ; ; STRUP: LD HL,OTOP ;START UP (NEW COMMAND) LD (OBTM),HL LD DE,STUPM CALL MSG RET STUPM DB 'TINY BASIC FOR CP/M',0DH EXIT: LD C,0 ;EXIT TO SYSTEM CALL 5 RET PUTCH: PUSH BC ;OUTPUT 1 CHAR PUSH DE LD E,A LD C,2 CALL 5 POP DE POP BC RET KBHIT: PUSH BC ;CHECK KEY STATUS LD C,11 CALL 5 XOR 00H POP BC RET GETCH: PUSH BC ;INPUT 1 CHAR LD C,1 CALL 5 CP 0DH JP NZ,NONL PUSH AF LD A,0AH CALL PUT POP AF NONL: POP BC RET ECODE: EQU $ ORG RAMST COBJ DS 0002H RSTCK DS 0002H NCNTR DS 0002H FCNTR DS 0002H FSTPV DS 0002H FTOV DS 0002H FLABL DS 0002H FOBJ DS 0002H RWRK DS 0002H OBTM DS 0002H OTOP DS 0001H END
元の東大版はインテル8080ニモニック表記なのは当然で、買うとお高いマクロアセンブラを使ってる。お安いXA80はマクロもリロケータブルも対応していなくてコメントとEQU定義とDB、DSくらいしか使えない。東大のお偉い教授サンとは使える環境が違ったんだよ。