Skip to content

Instantly share code, notes, and snippets.

@vintagechips
Last active April 3, 2021 05:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save vintagechips/043ae43549ae188a9f5946d4edd64a2d to your computer and use it in GitHub Desktop.
Save vintagechips/043ae43549ae188a9f5946d4edd64a2d to your computer and use it in GitHub Desktop.
Micro monitor for SBC8080/8085 with assembler/disassembler.
; uMON85 SBC8085 MICRO MONITOR
;
; DEFAULT VALUE
LINSIZ EQU 26 ; SIZE OF LINE BUFFER
;
; RESET VECTOR
ORG 0000H
RESET: LXI SP,LBUF ; スタック設定
JMP MAIN ; MAINから開始
;
; GET CHARACTOR
; A=CHARACTOR
GETCH: IN 1
ANI 00000010B
JZ GETCH
IN 0
RET
;
; PUT CHARACTOR
; A=CHARACTOR
PUTCH: PUSH PSW
DEBUG1: IN 1
ANI 00000001B
JZ DEBUG1
POP PSW
OUT 0
RET
;
; PUT STRING
; HL= *STRING
PUTS: MOV A,M ; 文字を拾う
CPI 0 ; もし0なら
JZ PSST1 ; 終了
CALL PUTCH ; 文字を送信
INX H ; 次の文字を指す
JMP PUTS ; 繰り返す
PSST1: RET ; 戻る
;
; GET STRING
; BROKEN A,DE,HL
GETS: LXI H,LBUF ; HLをバッファ内書き込み位置に設定
MVI E,0 ; C文字数をクリア
;
GSST5: CALL GETCH ; Aに文字を入れる
CPI 13 ; CR?
JZ GSST1 ; 一致なら終了処理へ分岐
;
; BSなら1文字削除
CPI 8 ; BS?
JNZ GSST4 ; 不一致なら次の処理へ
MOV A,E ; 比較の準備
CPI 0 ; バッファに文字がある?
JZ GSST5 ; 文字がなければ無視
MVI A,8 ; BSで
CALL PUTCH ; カーソルを戻す
MVI A,' ' ; 空白で
CALL PUTCH ; 文字を消す
MVI A,8 ; BSで
CALL PUTCH ; カーソルを戻す
DCR E ; 文字数を減らす
DCX H ; HL(バッファ内書き込み位置)を戻す
JMP GSST5 ; 繰り返す
;
GSST4: MOV D,A ; Aの文字を退避
MOV A,E ; 比較の準備
CPI LINSIZ-1 ; バッファがいっぱい?
JNC GSST5 ; いっぱいなら無視
;
; TABを空白に変換
MOV A,D ; 文字をAへ復帰
CPI 9 ; TAB?
JNZ GSST3 ; 不一致なら次の処理へ
MVI A,' ' ; 空白に変換
;
; 印字不可能文字をはじく
GSST3: CPI ' ' ; 印字可能文字の下限と比較
JC GSST5 ; 未満なら無視
CPI '~'+1 ; 印字可能文字の上限+1と比較
JNC GSST5 ; 以上なら無視
;
; 小文字を大文字に変換
CPI 'a' ; aと比較
JC GSST6 ; 未満なら次の処理へ
CPI 'z'+1 ; z+1と比較
JNC GSST6 ; 以上なら次の処理へ
ANI 0DFH ; 大文字に変換
;
; 入力した文字を保存
GSST6: MOV M,A ; バッファに文字を保存
INX H ; 書き込み位置を進める
INR E ; 文字数を増やす
CALL PUTCH ; エコーバック
JMP GSST5 ; 繰り返す
;
GSST1:; INX H ; 行末を指す
MVI M,0 ; 行末記号を保存
LXI H,CRLF ; 改行を
JMP PUTS ; 出力
;
;
; MAIN ROUTINE
MAIN:
MVI A,00H
OUT 1
OUT 1
OUT 1
MVI A,01000000B
OUT 1
MVI A,01001110B
OUT 1
MVI A,00110111B
OUT 1
; MVI A,TXIM OR 80H ; MARKを
; SIM ; 送信
;
; FILL IN RAM WITH 0
MVI A,0 ; DATA
MVI C,0 ; COUNTER
LXI H,0FF00H ; START ADDRESS
INIRAM: MOV M,A ; SET 0
INX H ; NEXT ADDRESS
DCR C ; STOP?
JNZ INIRAM ; IF NO, THEN REPEAT
;
LXI H,0FF00H ; INITIAL START ADDRESS
SHLD ADRSS ; SET IT
;
; OPENNING MESSAGE
LXI H,HELLO ; SET MESSAGE
CALL PUTS ; OUT IT
;
; DISPLAY PROMPT
LOOP: MVI A,'[' ; SET [
CALL PUTCH ; OUT IT
LHLD ADRSS ; GET START ADDRESS
CALL PUTW ; OUT IT
MVI A,']' ; SET ]
CALL PUTCH ; OUT IT
;
CALL GETS ; GET COMMAND LINE TO BUFFER
LXI D,LBUF ; SET DE TO BUFFER TOP
LDAX D ; GET CHAR
CPI ' ' ; SPACE?
JZ ERRCM ; THEN ERROR
CPI 0 ; EMPTY?
JZ LOOP ; THEN RETRY
;
; C COMMAND
COMC: CPI 'C' ; C?
JNZ COMG ; IF NOT, NEXT COMMAND
INX D ; NEXT CHAR
LDAX D ; GET CHAR
CPI ' ' ; SPACE?
JNZ ASMG1 ; IF NOT, GO ASSEMBLER
;
INX D ; NEXT CHAR
CALL GETW ; GET WORD
;
SHLD ADRSS ; UPDATE ADRSS
JMP LOOP
;
; G COMMAND
COMG: CPI 'G' ; G?
JNZ COMD ; Gでなければ次のコマンドを検査
INX D ; 次の文字へ進む
LDAX D ; 次の文字をAに転送
CPI ' ' ; 空白?
JNZ ASMG1 ; 空白でなければASMG1へ進む
;
INX D ; NEXT CHAR
CALL GETW ; GET WORD
;
LXI D,LOOP ; 戻りアドレスをBへ転送
PUSH D ; Bをスタックへ積む
PCHL ; ADRSSへ分岐
;
; D COMMAND
COMD: CPI 'D' ; D?
JNZ COML ; Dでなければ次のコマンドを検査
INX D ; 次の文字へ進む
LDAX D ; 次の文字をAに転送
CPI ' ' ; 空白?
JNZ ASMG1 ; 空白でなければASMG1へ進む
;
; 第1引数の処理
INX D ; NEXT CHAR
CALL GETW ; GET WORD
MOV A,L ; 開始アドレスを16個区切りに変換1
ANI 0F0H ; 開始アドレスを16個区切りに変換2
MOV L,A ; 開始アドレスを16個区切りに変換3
SHLD ADRSS ; ADRSSを更新
;
LDAX D ; 区切り文字を取得
CPI ',' ; 第2引数がある?
JZ CDST1 ; 第2引数があれば第2引数の処理
;
; 第2引数がなければ計算
MVI B,0 ; Bをクリア
MVI C,15 ; Cに15を転送
DAD B ; HL+BC
SHLD ADRSE ; ADRSSを更新
XCHG
LHLD ADRSS
JMP CDST2 ; 第2引数の処理をスキップ
;
; 第2引数の処理
CDST1: INX D ; 次の文字へ進む
CALL GETW ; 引数の値をHLに取得
SHLD ADRSE ; ADRSEを更新
;
XCHG
LHLD ADRSS
CALL CPDH
JNC CDST2
LXI D,LBUF+2
JMP ERRCM
;
; DUMP
CDST2: LXI H,INDENT ; インデントを
CALL PUTS ; 表示
LXI H,OFFSET ; オフセットを
CALL PUTS ; 表示
;
CDST3: MVI A,' '
CALL PUTCH
LHLD ADRSS ;先頭アドレス
CALL PUTW
MVI A,' '
CALL PUTCH
;
MVI C,16
CDST9: MOV A,M
CALL PUTB
MVI A,' '
CALL PUTCH
INX H
DCR C
JNZ CDST9
;
LHLD ADRSS
MVI C,16
CDST4: MOV A,M
CPI ' ' ; 印字可能文字の下限と比較
JC CDST5 ; 未満ならピリオド
CPI '~'+1 ; 印字可能文字の上限+1と比較
JNC CDST5 ; 以上ならピリオド
JMP CDST6
CDST5: MVI A,'.'
CDST6: CALL PUTCH
INX H
DCR C
JNZ CDST4
SHLD ADRSS
LXI H,CRLF
CALL PUTS
;
LHLD ADRSS
CALL CPDH
JC LOOP
MOV A,L
ORA H
JZ LOOP
JMP CDST3
;
; L COMMAND
COML: CPI 'L' ; D?
JNZ COMS ; Dでなければ次のコマンドを検査
INX D ; 次の文字へ進む
LDAX D ; 次の文字をAに転送
CPI ' ' ; 空白?
JNZ ASMG1 ; 空白でなければASMG1へ進む
;
; START ADDRESS
INX D ; NEXT CHAR
CALL GETW ; GET WORD
SHLD ADRSS ; ADRSSを更新
;
LDAX D ; 区切り文字を取得
CPI ',' ; 第2引数がある?
JZ CLST1 ; 第2引数があれば第2引数の処理
;
; 第2引数がなければ計算
LHLD ADRSS
SHLD ADRSE
JMP CLST2 ; 第2引数の処理をスキップ
;
; 第2引数の処理
CLST1: INX D ; 次の文字へ進む
CALL GETW ; 引数の値をHLに取得
SHLD ADRSE ; ADRSEを更新
;
XCHG
LHLD ADRSS
CALL CPDH
JNC CLST2
LXI D,LBUF+2
JMP ERRCM
;
; DIS ASSEMBLE
CLST2: CALL DASM
;
LHLD ADRSE ; DE
XCHG
LHLD ADRSS ; HL
CALL CPDH
JC LOOP
MOV A,L
ORA H
JZ LOOP
JMP CLST2
;
; S COMMAND
COMS: CPI 'S' ; S?
JNZ ASMG1 ; Sでなければ次のコマンドを検査
INX D ; 次の文字へ進む
LDAX D ; 次の文字をAに転送
CPI ' ' ; 空白?
JNZ ASMG1 ; 空白でなければASMG1へ進む
CSST8: INX D ; 次の文字へ進む
LDAX D ; GET CHAR
;
CSST1: CPI 0 ; 行末?
JZ LOOP ; 行末なら終了
LHLD ADRSS ; 書き込みアドレスを設定
;
; STRING
CPI 39 ; '?
JNZ CSST4 ; IF NOT, GO HEX
CSST3: INX D ; 次の文字へ進める
LDAX D ; 文字をAに取得
CPI 39 ; '?
JZ CSST2 ; 'ならこの処理を終了
CPI 0 ; 終端?
JZ ERRCM ; 終端ならエラー処理
MOV M,A ; HLの位置に文字を保存
INX H ; 書き込み位置を進める
SHLD ADRSS ; 開始位置を更新
JMP CSST3 ; この処理を継続
CSST2: INX D ; 'の後ろへ進める
LDAX D
CSST7: CPI ',' ; 区切り?
JZ CSST8 ; 区切りなら繰り返す
JMP LOOP ; 区切りでなければ終了
;
; HEX
; DEの退避にSVPTRを一時利用
CSST4: CALL GETW ; GET WORD
MOV A,L ; 16進数をAに転送
LHLD ADRSS ; 書き込み位置をHLに復帰
MOV M,A ; 書き込み位置に16進数を保存
INX H ; 書き込み位置を進める
SHLD ADRSS ; 書き込み位置を更新
LDAX D
CPI 0
JZ LOOP
CPI ','
JZ CSST8
JMP ERRCM
;
; ASSEMBLE GROUP1 OPCODE ONLY
ASMG1: LXI H,G1TBL ; SET GROUP TABLE POINTER
CALL MSRCH ; SEARCH MNEMONIC
CPI 0FFH ; NOT FOUND?
JZ ASMG2 ; THEN NEXT GROUP
;
INX H ; POINT CODE
MOV A,M ; GET CODE
;
; SAVE SINGLE CODE IN A
SVSC: LHLD ADRSS ; GET START ADDRES
MOV M,A ; SAVE CODE
INX H ; POINT NEXT ADDRESS
SHLD ADRSS ; UPDATE START ADDRES
JMP LOOP
;
; ASSEMBLE GROUP2 RST N
ASMG2: LXI H,G2TBL ; SET GROUP TABLE POINTER
CALL MSRCH ; SEARCH MNEMONIC
CPI 0FFH ; NOT FOUND?
JZ ASMG3 ; THEN NEXT GROUP
;
CPI ' ' ; SPACE?
JNZ ERRCM ; IF NOT, ERROR
INX H ; POINT CODE
MOV B,M ; GET CODE
;
INX D ; POINT NUMBER
LDAX D ; GET NUMBER CHAR
CALL GETW ; CONVERT TO NUMBER
MOV A,L ; CHECK NUMBER
CPI 8 ; COMPARE 8
JC A2ST1 ; IF LESS, OK
LHLD SVPTR ; POINT NUMBER STEP1
XCHG ; POINT NUMBER STEP2
JMP ERRCM ; ERROR
;
A2ST1: RLC ; MOVE POSITION STEP1
RLC ; MOVE POSITION STEP2
RLC ; MOVE POSITION STEP3
ORA B ; MAKE CODE
JMP SVSC ; SAVE SINGLE CODE
;
; ASSEMBLE GROUP3 OPCODE IMM8
ASMG3: LXI H,G3TBL ; SET GROUP TABLE POINTER
CALL MSRCH ; SEARCH MNEMONIC
CPI 0FFH ; NOT FOUND?
JZ ASMG4 ; THEN NEXT GROUP
;
CPI ' ' ; SPACE?
JNZ ERRCM ; IF NOT, ERROR
INX H ; POINT CODE
MOV B,M ; GET CODE
;
SVIMM8: INX D ; POINT IMM16
LDAX D ; GET IMM16 CHAR
CALL GETW ; CONVERT TO IMM16
MOV C,L ; SET IMM8
;
; SAVE 2 CODE IN BC
SV2C LHLD ADRSS ; GET START ADDRES
MOV M,B ; SAVE CODE
INX H ; POINT NEXT ADDRESS
MOV M,C ; SAVE IMM8
INX H ; POINT NEXT ADDRESS
SHLD ADRSS ; UPDATE START ADDRES
JMP LOOP
;
; ASSEMBLE GROUP4 OPCODE IMM16
ASMG4: LXI H,G4TBL ; SET GROUP TABLE POINTER
CALL MSRCH ; SEARCH MNEMONIC
CPI 0FFH ; NOT FOUND?
JZ ASMG5 ; THEN NEXT GROUP
;
CPI ' ' ; SPACE?
JNZ ERRCM ; IF NOT, ERROR
INX H ; POINT CODE
MOV B,M ; GET CODE
;
SVW3C: INX D ; POINT IMM16
; LDAX D ; GET IMM16 CHAR
CALL GETW ; CONVERT TO IMM16
XCHG ; SET IMM16 TO DE
;
; SAVE 3 CODE IN BC
SV3C LHLD ADRSS ; GET START ADDRES
MOV M,B ; SAVE CODE
INX H ; POINT NEXT ADDRESS
MOV M,E ; SAVE IMM16 LOW
INX H ; POINT NEXT ADDRESS
MOV M,D ; SAVE IMM16 HIGH
INX H ; POINT NEXT ADDRESS
SHLD ADRSS ; UPDATE START ADDRES
JMP LOOP
;
; ASSEMBLE GROUP5 OPCODE R(DDD)
ASMG5: LXI H,G5TBL ; SET GROUP TABLE POINTER
CALL MSRCH ; SEARCH MNEMONIC
CPI 0FFH ; NOT FOUND?
JZ ASMG6 ; THEN NEXT GROUP
;
CPI ' ' ; SPACE?
JNZ ERRCM ; IF NOT, ERROR
INX H ; POINT CODE
MOV B,M ; GET CODE
;
INX D ; POINT REGISTER NAME
LDAX D ; GET REGISTER NAME
CALL GETR ; CONVERT TO REGISTER NUMBER
RLC ; MOVE POSITION STEP1
RLC ; MOVE POSITION STEP2
RLC ; MOVE POSITION STEP3
ORA B ; MAKE CODE
JMP SVSC ; SAVE SINGLE CODE
;
; ASSEMBLE GROUP6 OPCODE R(SSS)
ASMG6: LXI H,G6TBL ; SET GROUP TABLE POINTER
CALL MSRCH ; SEARCH MNEMONIC
CPI 0FFH ; NOT FOUND?
JZ ASMG7 ; THEN NEXT GROUP
;
CPI ' ' ; SPACE?
JNZ ERRCM ; IF NOT, ERROR
INX H ; POINT CODE
MOV B,M ; GET CODE
;
SVSSS: INX D ; POINT REGISTER NAME
LDAX D ; GET REGISTER NAME
CALL GETR ; CONVERT TO REGISTER NUMBER
ORA B ; MAKE CODE
JMP SVSC ; SAVE SINGLE CODE
;
; GROUP7 OPCODE R(DDD),R(SSS)
ASMG7: LXI H,G7TBL ; SET GROUP TABLE POINTER
CALL MSRCH ; SEARCH MNEMONIC
CPI 0FFH ; NOT FOUND?
JZ ASMG8 ; THEN NEXT GROUP
;
CPI ' ' ; SPACE?
JNZ ERRCM ; IF NOT, ERROR
INX H ; POINT CODE
MOV B,M ; GET CODE
;
INX D ; POINT REGISTER NAME
LDAX D ; GET REGISTER NAME
CALL GETR ; CONVERT TO REGISTER NUMBER
RLC ; MOVE POSITION STEP1
RLC ; MOVE POSITION STEP2
RLC ; MOVE POSITION STEP3
ORA B ; MAKE CODE
MOV B,A ; SET IT TO B
;
INX D ; POINT REGISTER NAME
LDAX D ; GET REGISTER NAME
CPI ',' ; COMMA?
JNZ ERRCM ; IF NOT, ERROR
;
JMP SVSSS
;
; GROUP8 OPCODE R,IMM8
ASMG8: LXI H,G8TBL ; SET GROUP TABLE POINTER
CALL MSRCH ; SEARCH MNEMONIC
CPI 0FFH ; NOT FOUND?
JZ ASMG9 ; THEN NEXT GROUP
;
CPI ' ' ; SPACE?
JNZ ERRCM ; IF NOT, ERROR
INX H ; POINT CODE
MOV B,M ; GET CODE
;
INX D ; POINT REGISTER NAME
LDAX D ; GET REGISTER NAME
CALL GETR ; CONVERT TO REGISTER NUMBER
RLC ; MOVE POSITION STEP1
RLC ; MOVE POSITION STEP2
RLC ; MOVE POSITION STEP3
ORA B ; MAKE CODE
MOV B,A ; SET IT TO B
;
INX D ; POINT REGISTER NAME
LDAX D ; GET REGISTER NAME
CPI ',' ; COMMA?
JNZ ERRCM ; IF NOT, ERROR
JMP SVIMM8 ; GET IMM8 AND SAVE 2 CODE IN BC
;
; GROUP9 OPCODE RP,IMM16
ASMG9: LXI H,G9TBL ; SET GROUP TABLE POINTER
CALL MSRCH ; SEARCH MNEMONIC
CPI 0FFH ; NOT FOUND?
JZ ASMGA ; THEN NEXT GROUP
;
CPI ' ' ; SPACE?
JNZ ERRCM ; IF NOT, ERROR
INX H ; POINT CODE
MOV B,M ; GET CODE
;
INX D ; POINT REGISTER PAIR NAME
CALL GETRP ; CONVERT TO REGISTER PAIR NUMBER
RLC ; MOVE POSITION STEP1
RLC ; MOVE POSITION STEP2
RLC ; MOVE POSITION STEP3
RLC ; MOVE POSITION STEP4
ORA B ; MAKE CODE
MOV B,A ; SET IT TO B
;
INX D ; NEXT CHAR
LDAX D ; GET CHAR
CPI ',' ; COMMA?
JNZ ERRCM ; IF NOT, ERROR
;
JMP SVW3C
;
; OPCODE RP
ASMGA: LXI H,GATBL ; SET GROUP TABLE POINTER
CALL MSRCH ; SEARCH MNEMONIC
CPI 0FFH ; NOT FOUND?
JZ ASMGB ; THEN NEXT GROUP
;
CPI ' ' ; SPACE?
JNZ ERRCM ; IF NOT, ERROR
INX H ; POINT CODE
MOV B,M ; GET CODE
;
INX D ; POINT REGISTER PAIR NAME
CALL GETRP ; CONVERT TO REGISTER PAIR NUMBER
SVRP: RLC ; MOVE POSITION STEP1
RLC ; MOVE POSITION STEP2
RLC ; MOVE POSITION STEP3
RLC ; MOVE POSITION STEP4
ORA B ; MAKE CODE
JMP SVSC ; SAVE SINGLE CODE
;
; OPCODE RP(B OR D)
ASMGB: LXI H,GBTBL ; SET GROUP TABLE POINTER
CALL MSRCH ; SEARCH MNEMONIC
CPI 0FFH ; NOT FOUND?
JZ ASMNG ; THEN NEXT GROUP
;
CPI ' ' ; SPACE?
JNZ ERRCM ; IF NOT, ERROR
INX H ; POINT CODE
MOV B,M ; GET CODE
;
INX D ; POINT REGISTER PAIR NAME
CALL GETRP ; CONVERT TO REGISTER PAIR NUMBER
;
CPI 2 ; ONLY B OR D
JNC ERRCM ; IF NOT, ERROR
JMP SVRP ; GET RP AND SAVE SINGLE CODE
;
; UNKNOWN COMMANE OR MNEMONIC
ASMNG: LXI D,LBUF ; POINT COMMAND LINE
JMP ERRCM ; ERROR
;
; GET REGISTOR NUMBER
; A=REGISTER NAME
; A=REGISTER NUMBER
GETR: CPI 'A' ; A?
JNZ GRST1 ; Aでなければ次の検査
MVI A,7 ; Aなら7と置き換える
RET
GRST1: CPI 'H'
JNZ GRST2
MVI A,4
RET
GRST2: CPI 'L'
JNZ GRST3
MVI A,5
RET
GRST3: CPI 'M'
JNZ GRST4
MVI A,6
RET
GRST4: CPI 'B' ; Bと比較
JC ERRCM ; 未満ならエラー処理
CPI 'E'+1 ; E+1と比較
JNC ERRCM ; 以上ならエラー処理
SUI 'B' ; レジスタ番号を計算
RET
;
; GET WORD
; DE=HEX STRING
; HL=WORD,A=TERM
; BROKEN SVPTR
GETW: XCHG ; SAVE DE STEP1
SHLD SVPTR ; SAVE DE STEP2
XCHG ; RESTORE HL
;
; TEST HEX CHAR
MVI C,0 ; カウンタをクリア
SXST3: LDAX D ; DEが指す文字をAに転送
CPI '0' ; 0?
JC GWST2 ; 0未満の文字なら戻る
CPI '9'+1 ; 9?
JC SXST2 ; 9以下の文字なら次の処理へ進む
CPI 'A' ; A?
JC GWST2 ; A未満の文字なら戻る
CPI 'F'+1 ; F以上?
JNC GWST2 ; F以上の文字なら戻る
SXST2: INR C ; 文字数を増やす
INX D ; DEを進める
JMP SXST3 ; 繰り返す
;
GWST2: MOV A,C ; 文字数をAに転送
CPI 0 ; 文字数0?
JZ ERRCM ; 文字数0ならエラー処理
;
; 引数を取得
LHLD SVPTR ; HLを復帰
XCHG ; HLとDEを入れ替え
;
; XTOW
; DE=*HEX,A=HEX文字数(1以上)
; HL=WORD,DE=*区切り文字
XTOW: LXI H,0 ; HLをクリア
;
CPI 1 ; 文字数が1でなければ
JNZ XWST2 ; 次の処理へ進む
XWST1: LDAX D ; 文字をAに転送
CALL HTOB ; 16進数文字をバイナリに変換
ORA L ; AとLを重ねる
MOV L,A ; Lに転送
INX D ; DEを進める
JMP GWST1
;
XWST2: CPI 2 ; 文字数が2でなければ
JNZ XWST3 ; 次の処理へ進む
XWST5: LDAX D ; DEが指す文字をAに転送
CALL HTOB ; 16進数文字をバイナリに変換
RLC ; 左へローテート
RLC ; 左へローテート
RLC ; 左へローテート
RLC ; 左へローテート
ANI 0F0H ; ゴミを除去
MOV L,A ; Lに転送
INX D ; DEを進める
JMP XWST1 ; 残り文字の処理
;
XWST3: CPI 3 ; 文字数が3でなければ
JNZ XWST4 ; 次の処理へ進む
XWST8: LDAX D ; DEが指す文字をAに転送
CALL HTOB ; 16進数文字をバイナリに変換
ORA H ; AとHを重ねる
MOV H,A ; Hに転送
INX D ; DEを進める
JMP XWST5 ; 残り文字の処理
;
XWST4: CPI 4 ; 文字数が4でなければ
JNZ XWST6 ; 次の処理へ進む
XWST7: LDAX D ; DEが指す文字をAに転送
CALL HTOB ; 16進数文字をバイナリに変換
RLC ; 左へローテート
RLC ; 左へローテート
RLC ; 左へローテート
RLC ; 左へローテート
ANI 0F0H ; ゴミを除去
MOV H,A ; Hに転送
INX D ; DEを進める
JMP XWST8 ; 残り文字の処理
;
XWST6: SBI 4 ; 文字数から4を引く
XWST9: INX D ; DEを進める
DCR A ; 文字数を減らす
JNZ XWST9 ; 0でなければ繰り返す
JMP XWST7 ; 文字数4の処理へ進む
;
; CALL XTOW ; 16進数をHLに取得
;
GWST1: LDAX D ; 区切り文字をAに転送
RET
;
; DE=RP STRING
; A=RP NUMBER,DE=LAST CHAR
GETRP: LDAX D
CPI 'B'
JNZ GRPS1
MVI A,0
RET
GRPS1: CPI 'D'
JNZ GRPS2
MVI A,1
RET
GRPS2: CPI 'H'
JNZ GRPS3
MVI A,2
RET
GRPS3: CPI 'S'
JNZ GRPS4
INX D
LDAX D
CPI 'P'
JNZ ERRCM
MVI A,3
RET
GRPS4: CPI 'P'
JNZ ERRCM
INX D
LDAX D
CPI 'S'
JNZ ERRCM
INX D
LDAX D
CPI 'W'
JNZ ERRCM
MVI A,3
RET
;
; COMMAND LINE ERROR
ERRCM: LXI H,ERROR ; ERROR-を
CALL PUTS ; 表示
LXI H,LBUF ; コマンドラインを
CALL PUTS ; 表示
LXI H,CRLF ; 改行を
CALL PUTS ; 表示
LXI H,INDENT ; インデントを
CALL PUTS ; 表示
;
MOV A,E
MVI E,LBUF AND 00FFH
SUB E
JZ ECST2
;
MOV E,A
MVI A,' '
ECST1: CALL PUTCH
DCR E
JNZ ECST1
;
ECST2: MVI A,'^'
CALL PUTCH
LXI H,CRLF
CALL PUTS
LXI SP,LBUF ; スタック設定
JMP LOOP
;
; COMMON ROUTINE TO PERFORM UNSIGNED COMPARE
; CARRY SET IF DE < HL
; 破壊されるレジスタ-A
CPDH: MOV A,D
CMP H
RNZ
MOV A,E
CMP L
RET
;
; CONVERT BIN TO HEX CHAR
; A=BIN(NIBBLE)
; A=HEX CHAR
BTOH: ANI 0FH ; ゴミを除去
CPI 10 ; 10?
JC BHST1 ; 10未満の文字なら次の処理へ進む
ADI 'A'-10 ;
RET
BHST1: ADI '0'
RET
;
; PUT BYTE
; A=BYTE
PUTB: PUSH PSW ; 16進数を退避
RRC ; 16進数1桁めへ変換
RRC ; 16進数1桁めへ変換
RRC ; 16進数1桁めへ変換
RRC ; 16進数1桁めへ変換
CALL BTOH ; 16進数1桁めを文字に変換
CALL PUTCH ; 16進数1桁めを表示
POP PSW ; 16進数を復帰
CALL BTOH ; 16進数1桁めを文字に変換
JMP PUTCH ; 16進数1桁めを表示
;
; PUT WORD
; HL=WORD
PUTW: MOV A,H ; 上位バイトをAに転送
CALL PUTB ; 16進数1桁めを表示
MOV A,L ; 下位バイトをAに転送
JMP PUTB ; 16進数1桁めを表示
;
; CONVERT HEX CHAR TO BIN
; A=HEX CHAR
; A=BIN
HTOB: CPI 'A' ; A?
JC HBST1 ; A未満の文字なら次の処理へ進む
SUI 'A'-10 ;
RET
HBST1: SUI '0'
RET
;
; SEARCH MNEMONIC GROUP TABLE
; HL=VECTOR TABLE
; A=FF(NOT FOUND IN THIS GROUP),DE=TERM,HL=VECTOR(IF FOUND)
; BROKEN SVPTR
MSRCH: MOV A,M ; GET VECTOR LOW
CPI 0FFH ; TERM?
RZ ; THEN RETURN(A=FF)
SHLD SVPTR ; SAVE VECTOR
MOV L,A ; MNEMONIC LOW
MVI H,MTBL/256 ; MNEMONIC HIGH
LXI D,LBUF ; POINT MNEMONIC IN BUFFER
;
; COMPARE 1 MNEMONIC
MCST1: LDAX D ; GET CHAR
CMP M ; SAME?
JZ MCST2 ; THEN SKIP FOLLOW
;
; CASE NOT SAME
ORI 20H ; CONVERT SMALL
CMP M ; SAME?
LHLD SVPTR ; RESTORE VECTOR
JNZ MSST1 ; IF NOT, NEXT VECTOR
;
; COMPLETE DONE?
INX D ; POINT NEXT CHAR
LDAX D ; GET CHAR
CPI ' ' ; SPACE?
RZ ; SURE THEN RETURN(Z)
CPI ',' ; COMMA?
RZ ; SURE THEN RETURN(Z)
CPI 0 ; TERM?
RZ ; SURE RETURN(Z)
JMP MSST1 ; IF NOT, NEXT VECTOR
;
MCST2: INX D ; POINT NEXT CHAR
INX H ; POINT NEXT CHAR
JMP MCST1
MSST1: INX H ; POINT NEXT VECTOR
INX H ; POINT NEXT VECTOR
JMP MSRCH
;
; PUT MNEMONIC
; L= MNEMONIC ADDRESS LOW
; BROKEN A(NOT FF),HL(LAST CHAR)
PUTM: MVI H,MTBL/256
PMST2: MOV A,M ; GET CHAR
CPI 'a' ; SMALL?
JNC PMST1 ; IF YES, GO FINAL
;
CALL PUTCH ; PUT IT
INX H ; NEXT CHAR
JMP PMST2 ; REPEAT
;
PMST1: ANI 0DFH ; CONVERT CAPITAL
JMP PUTCH ; PUT IT
;
; PUT REGISTER NAME
; A=REGISTER NUMBER
PUTR: LXI H,RNAME ; GET TOP
PRST3: ADD L
MOV L,A
MOV A,M
JMP PUTCH
;
; PUT RP NAME
; A=RP NUMBER
PUTRP: CPI 3 ; IRREGULAR?
JNC PRST1 ; IF YES, PUT SP
PRST2: LXI H,RPNAME ; GET TOP
JMP PRST3
;
PRST1: LXI H,RPSP
JMP PUTS
;
; PUT RP NAME(3=PSW)
; A=RP NUMBER
PUTPSW: CPI 3 ; IRREGULAR?
JNC PPST1 ; IF YES, PUT SP
JMP PRST2
;
PPST1: LXI H,RPPSW
JMP PUTS
;
; SEARCH CODE IN GROUP TABLE
; HL=VECTOR TABLE,B=CODE
; A=FF(NOT FOUND IN THIS GROUP),A=CODE(FOUND)
; BROKEN HL
CSRCH: MOV A,M ; GET VECTOR
CPI 0FFH ; TERM?
RZ ; IF YES, RETURN(A=FF)
;
INX H ; POINT CODE
MOV A,M ; GET CODE
CMP B ; SAME?
JZ CSRS1 ; IF YES, PUT IT
;
INX H ; POINT NEXT VECTOR
JMP CSRCH ; REPEAT
;
CSRS1: DCX H ; POINT VECTOR
MOV L,M ; GET LOW
JMP PUTM
;
; DIS ASSEMBLER
DASM: MVI A,' ' ; SET SPACE
CALL PUTCH ; OUT IT
LHLD ADRSS ; GET START ADDRESS
CALL PUTW ; OUT IT
MVI A,' ' ; SET SPACE
CALL PUTCH ; OUT IT
;
MOV B,M ; GET CODE(FIRST, USE HL)
XCHG ; SET START ADDRESS TO DE
;
G1GP: LXI H,G1TBL ; CODE ONRY
CALL CSRCH ; SEARCH CODE
CPI 0FFH ; NOT FOUND?
JZ G2GP ; THEN NEXT GROUP
JMP DAST1 ; NO OPERAND
;
G2GP: PUSH B ; SAVE CODE
MOV A,B ; MASK NUMBER STEP1
ANI 0C7H ; MASK NUMBER STEP2
MOV B,A ; MASK NUMBER STEP3
;
LXI H,G2TBL ; CODE WITH NUMBER
CALL CSRCH ; SEARCH CODE
POP B ; RESTORE CODE
CPI 0FFH ; NOT FOUND?
JZ G3GP ; THEN NEXT GROUP
;
; NUMBER
MVI A,' ' ; SET SPACE
CALL PUTCH ; OUT IT
MOV A,B
RRC
RRC
RRC
ANI 07H
CPB: CALL PUTB
JMP DAST1
;
G3GP: LXI H,G3TBL ; CODE+IMM8
CALL CSRCH ; SEARCH CODE
CPI 0FFH ; NOT FOUND?
JZ G4GP ; THEN NEXT GROUP
;
; IMM8
MVI A,' ' ; SET SPACE
CALL PUTCH ; OUT IT
INX D
LDAX D
JMP CPB
;
G4GP: LXI H,G4TBL ; CODE+IMM16
CALL CSRCH ; SEARCH CODE
CPI 0FFH ; NOT FOUND?
JZ G5GP ; THEN NEXT GROUP
;
; IMM16
MVI A,' ' ; SET SPACE
CALL PUTCH ; OUT IT
SIMM16: INX D
LDAX D
MOV L,A
INX D
LDAX D
MOV H,A
CALL PUTW
JMP DAST1
;
G5GP: PUSH B ; SAVE CODE
MOV A,B ; MASK NUMBER STEP1
ANI 0C7H ; MASK NUMBER STEP2
MOV B,A ; MASK NUMBER STEP3
;
LXI H,G5TBL ; CODE WITH NUMBER
CALL CSRCH ; SEARCH CODE
POP B ; RESTORE CODE
CPI 0FFH ; NOT FOUND?
JZ G6GP ; THEN NEXT GROUP
;
; REGISTER NAME(DDD)
MVI A,' ' ; SET SPACE
CALL PUTCH ; OUT IT
MOV A,B
RRC
RRC
RRC
ANI 07H
CALL PUTR
JMP DAST1
;
G6GP: PUSH B ; SAVE CODE
MOV A,B ; MASK NUMBER STEP1
ANI 0F8H ; MASK NUMBER STEP2
MOV B,A ; MASK NUMBER STEP3
;
LXI H,G6TBL ; CODE WITH NUMBER
CALL CSRCH ; SEARCH CODE
POP B ; RESTORE CODE
CPI 0FFH ; NOT FOUND?
JZ G7GP ; THEN NEXT GROUP
;
; REGISTER NAME(SSS)
MVI A,' ' ; SET SPACE
CALL PUTCH ; OUT IT
MOV A,B
ANI 07H
CALL PUTR
JMP DAST1
;
G7GP: PUSH B ; SAVE CODE
MOV A,B ; MASK NUMBER STEP1
ANI 0C0H ; MASK NUMBER STEP2
MOV B,A ; MASK NUMBER STEP3
;
LXI H,G7TBL ; CODE WITH NUMBER
CALL CSRCH ; SEARCH CODE
POP B ; RESTORE CODE
CPI 0FFH ; NOT FOUND?
JZ G8GP ; THEN NEXT GROUP
;
; REGISTER NAME(DDD,SSS)
MVI A,' ' ; SET SPACE
CALL PUTCH ; OUT IT
;
PUSH B
MOV A,B
RRC
RRC
RRC
ANI 07H
CALL PUTR
;
MVI A,',' ; SET COMMA
CALL PUTCH ; OUT IT
POP B
MOV A,B
ANI 07H
CALL PUTR
JMP DAST1
;
G8GP: PUSH B ; SAVE CODE
MOV A,B ; MASK NUMBER STEP1
ANI 0C7H ; MASK NUMBER STEP2
MOV B,A ; MASK NUMBER STEP3
;
LXI H,G8TBL ; CODE WITH NUMBER
CALL CSRCH ; SEARCH CODE
POP B ; RESTORE CODE
CPI 0FFH ; NOT FOUND?
JZ G9GP ; THEN NEXT GROUP
;
; REGISTER NAME(DDD),IMM8
MVI A,' ' ; SET SPACE
CALL PUTCH ; OUT IT
MOV A,B
RRC
RRC
RRC
ANI 07H
CALL PUTR
;
MVI A,',' ; SET COMMA
CALL PUTCH ; OUT IT
INX D
LDAX D
JMP CPB
;
G9GP: PUSH B ; SAVE CODE
MOV A,B ; MASK NUMBER STEP1
ANI 0CFH ; MASK NUMBER STEP2
MOV B,A ; MASK NUMBER STEP3
;
LXI H,G9TBL ; CODE WITH NUMBER
CALL CSRCH ; SEARCH CODE
POP B ; RESTORE CODE
CPI 0FFH ; NOT FOUND?
JZ GAGP ; THEN NEXT GROUP
;
; REGISTER PAIR NAME(RP),IMM16
MVI A,' ' ; SET SPACE
CALL PUTCH ; OUT IT
MOV A,B
RRC
RRC
RRC
RRC
ANI 03H
CALL PUTRP
;
MVI A,',' ; SET COMMA
CALL PUTCH ; OUT IT
JMP SIMM16
;
GAGP: PUSH B ; SAVE CODE
MOV A,B ; MASK NUMBER STEP1
ANI 0CFH ; MASK NUMBER STEP2
MOV B,A ; MASK NUMBER STEP3
;
LXI H,GATBL ; CODE WITH NUMBER
CALL CSRCH ; SEARCH CODE
POP B ; RESTORE CODE
CPI 0FFH ; NOT FOUND?
JZ GBGP ; THEN NEXT GROUP
;
; REGISTER PAIR NAME(RP)
MVI A,' ' ; SET SPACE
CALL PUTCH ; OUT IT
MOV A,B
RRC
RRC
RRC
RRC
ANI 03H
PUSH PSW
;
MOV A,B
ANI 0C0H
JZ GAS1
POP PSW
CALL PUTPSW
JMP DAST1
;
GAS1: POP PSW
CALL PUTRP
JMP DAST1
;
GBGP: PUSH B ; SAVE CODE
MOV A,B ; MASK NUMBER STEP1
ANI 0CFH ; MASK NUMBER STEP2
MOV B,A ; MASK NUMBER STEP3
;
LXI H,GBTBL ; CODE WITH NUMBER
CALL CSRCH ; SEARCH CODE
POP B ; RESTORE CODE
CPI 0FFH ; NOT FOUND?
JZ GNGP ; THEN NEXT GROUP
;
; REGISTER PAIR NAME(RP)
MVI A,' ' ; SET SPACE
CALL PUTCH ; OUT IT
MOV A,B
RRC
RRC
RRC
RRC
ANI 03H
CALL PUTRP
JMP DAST1
;
GNGP: MVI A,'?'
CALL PUTCH
;
DAST1: LXI H,CRLF
CALL PUTS
INX D
XCHG
SHLD ADRSS
RET
;
; MESSAGE
HELLO DB 'MICRO MONITOR V1.0 FOR MCS8085',0DH,0AH
CRLF DB 0DH,0AH,0
ERROR DB 'ERROR-',0
INDENT DB ' ',0
OFFSET DB '+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F ASCII',0DH,0AH,0
;
; GROUP VECTOR TABLE
G1TBL DB MNOP AND 0FFH,00H
DB MRLC AND 0FFH,07H
DB MRRC AND 0FFH,0FH
DB MRAL AND 0FFH,17H
DB MRAR AND 0FFH,1FH
DB MDAA AND 0FFH,27H
DB MCMA AND 0FFH,2FH
DB MSTC AND 0FFH,37H
DB MCMC AND 0FFH,3FH
DB MHLT AND 0FFH,76H
DB MRNZ AND 0FFH,0C0H
DB MRZ AND 0FFH,0C8H
DB MRET AND 0FFH,0C9H
DB MRNC AND 0FFH,0D0H
DB MRC AND 0FFH,0D8H
DB MRPO AND 0FFH,0E0H
DB MRPE AND 0FFH,0E8H
DB MRP AND 0FFH,0F0H
DB MRM AND 0FFH,0F8H
DB MXTHL AND 0FFH,0E3H
DB MPCHL AND 0FFH,0E9H
DB MXCHG AND 0FFH,0EBH
DB MSPHL AND 0FFH,0F9H
DB MDI AND 0FFH,0F3H
DB MEI AND 0FFH,0FBH
DB MRIM AND 0FFH,20H
DB MSIM AND 0FFH,30H
DB 0FFH
;
G2TBL DB MRST AND 0FFH,0C7H
DB 0FFH
;
G3TBL DB MIN AND 0FFH,0DBH
DB MOUT AND 0FFH,0D3H
DB MADI AND 0FFH,0C6H
DB MACI AND 0FFH,0CEH
DB MSUI AND 0FFH,0D6H
DB MSBI AND 0FFH,0DEH
DB MANI AND 0FFH,0E6H
DB MXRI AND 0FFH,0EEH
DB MORI AND 0FFH,0F6H
DB MCPI AND 0FFH,0FEH
DB 0FFH
;
G4TBL DB MSHLD AND 0FFH,22H
DB MLHLD AND 0FFH,2AH
DB MSTA AND 0FFH,32H
DB MLDA AND 0FFH,3AH
DB MJNZ AND 0FFH,0C2H
DB MJMP AND 0FFH,0C3H
DB MCNZ AND 0FFH,0C4H
DB MJZ AND 0FFH,0CAH
DB MCZ AND 0FFH,0CCH
DB MCALL AND 0FFH,0CDH
DB MJNC AND 0FFH,0D2H
DB MCNC AND 0FFH,0D4H
DB MJC AND 0FFH,0DAH
DB MCC AND 0FFH,0DCH
DB MJPO AND 0FFH,0E2H
DB MCPO AND 0FFH,0E4H
DB MJPE AND 0FFH,0EAH
DB MCPE AND 0FFH,0ECH
DB MJP AND 0FFH,0F2H
DB MCP AND 0FFH,0F4H
DB MJM AND 0FFH,0FAH
DB MCM AND 0FFH,0FCH
DB 0FFH
;
G5TBL DB MINR AND 0FFH,04H
DB MDCR AND 0FFH,05H
DB 0FFH
;
G6TBL DB MADD AND 0FFH,80H
DB MADC AND 0FFH,88H
DB MSUB AND 0FFH,90H
DB MSBB AND 0FFH,98H
DB MANA AND 0FFH,0A0H
DB MXRA AND 0FFH,0A8H
DB MORA AND 0FFH,0B0H
DB MCMP AND 0FFH,0B8H
DB 0FFH
;
G7TBL DB MMOV AND 0FFH,40H
DB 0FFH
;
G8TBL DB MMVI AND 0FFH,06H
DB 0FFH
;
G9TBL DB MLXI AND 0FFH,01H
DB 0FFH
;
GATBL DB MINX AND 0FFH,03H
DB MDAD AND 0FFH,09H
DB MDCX AND 0FFH,0BH
DB MPOP AND 0FFH,0C1H
DB MPUSH AND 0FFH,0C5H
DB 0FFH
;
GBTBL DB MLDAX AND 0FFH,0AH
DB MSTAX AND 0FFH,02H
DB 0FFH
;
; ADDRESS DEPENDANT CODE
; DON'T MOVE!!
TBLADR EQU $
ORG ((TBLADR - 1) AND 0FF00H) + 0100H
MTBL
;
; GROUP1 OPCODE ONLY
MNOP DB 'NOp'
MRLC DB 'RLc'
MRRC DB 'RRc'
MRAL DB 'RAl'
MRAR DB 'RAr'
MDAA DB 'DAa'
MCMA DB 'CMa'
MSTC DB 'STc'
MCMC DB 'CMc'
MHLT DB 'HLt'
MRNZ DB 'RNz'
MRZ DB 'Rz'
MRET DB 'REt'
MRNC DB 'RNc'
MRC DB 'Rc'
MRPO DB 'RPo'
MRPE DB 'RPe'
MRP DB 'Rp'
MRM DB 'Rm'
MXTHL DB 'XTHl'
MPCHL DB 'PCHl'
MXCHG DB 'XCHg'
MSPHL DB 'SPHl'
MDI DB 'Di'
MEI DB 'Ei'
MRIM DB 'RIm'
MSIM DB 'SIm'
;
; GROUP2 RST N
MRST DB 'RSt'
;
; GROUP3 OPCODE IMM8
MIN DB 'In'
MOUT DB 'OUt'
MADI DB 'ADi'
MACI DB 'ACi'
MSUI DB 'SUi'
MSBI DB 'SBi'
MANI DB 'ANi'
MXRI DB 'XRi'
MORI DB 'ORi'
MCPI DB 'CPi'
;
; GROUP4 OPCODE IMM16
MSHLD DB 'SHLd'
MLHLD DB 'LHLd'
MSTA DB 'STa'
MLDA DB 'LDa'
MJNZ DB 'JNz'
MJMP DB 'JMp'
MCNZ DB 'CNz'
MJZ DB 'Jz'
MCZ DB 'Cz'
MCALL DB 'CALl'
MJNC DB 'JNc'
MCNC DB 'CNc'
MJC DB 'Jc'
MCC DB 'Cc'
MJPO DB 'JPo'
MCPO DB 'CPo'
MJPE DB 'JPe'
MCPE DB 'CPe'
MJP DB 'Jp'
MCP DB 'Cp'
MJM DB 'Jm'
MCM DB 'Cm'
;
; GROUP5 OPCODE R(DDD)
MDCR: DB 'DCr'
MINR: DB 'INr'
;
; GROUP6 OPCODE R(SSS)
MADD DB 'ADd'
MADC DB 'ADc'
MSUB DB 'SUb'
MSBB DB 'SBb'
MANA DB 'ANa'
MXRA DB 'XRa'
MORA DB 'ORa'
MCMP DB 'CMp'
;
; GROUP7 OPCODE R(DDD),R(SSS)
MMOV DB 'MOv'
;
; GROUP8 OPCODE R,IMM8
MMVI DB 'MVi'
;
; GROUP9 OPCODE RP(SPとPSWを区別しない)
MLXI DB 'LXi'
MINX DB 'INx'
MDAD DB 'DAd'
MDCX DB 'DCx'
MPUSH DB 'PUSh'
MPOP DB 'POp'
;
; GROUP10 OPCODE RP(B OR D)
MLDAX DB 'LDAx'
MSTAX DB 'STAx'
;
; REGISTER NAME
RNAME DB 'BCDEHLMA'
RPNAME DB 'BDH'
RPSP DB 'SP',0
RPPSW DB 'PSW',0
;
ORG 0-LINSIZ-6
LBUF DS LINSIZ
SVPTR DS 2
ADRSS DS 2
ADRSE DS 2
;
END
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment