[BITS 16] [OPTIMIZE 1] [OPTION 1] [INSTRSET "8086"] [FORMAT "BIN"] ORG 0x100 ;----------------------------------------------------- ;--- こっから上は、MS-DOSの.COMを作る時の ------------ ;----おまじないだと思ってくれい!     ------------ ;----------------------------------------------------- ;-------- 実験部分 ---------------------- ;初期設定部 ;BIOSで画面全体をクリアする MOV AL,0 MOV BH,0x0F MOV CH,0 MOV CL,0 MOV DH,25 MOV DL,80 MOV AH,0x06 INT 0x10 ;BIOSでカーソルを0,0の位置に移動 MOV DH,0 MOV DL,0 MOV AH,0x02 INT 0x10 ;プロンプトを表示 CALL PROMPTPRINT ;BIOSのキー入力を乗っ取る MOV AX,0 MOV ES,AX ; ESを0にする。 MOV WORD[ES:0x09*4+0],IINT09 MOV WORD[ES:0x09*4+2],CS MOV AX,DS MOV ES,AX ; ESをもとにもどす。 JMP MAINLLP ;メインループへジャンプ ;メインのループ部分 MAINLLP: JMP MAINLLP ;乗っ取ったキーボード割り込み部分 IINT09: ;押されたキーは何かを調べる ;IN命令で、押されたキーの値を取得 MOV DX,0x60 IN AL,DX ;持ってきた値を一時、AHに複製する MOV AH,AL ;AHに複製した値の7ビット目だけを摘出 AND AH,0x80 ;もし、この結果の値が00000000すなわち0x0なら、 ;キーは「押された」となるはず。ここで条件分岐 CMP AH,0x0 ;なにもせずに割り込みを終了する JE INTEND ;持ってきた値の7ビットだけを抽出 AND AL,0x7F ;二進数 01111111 でANDSする ;もしその値が1Eだったら、Aボタンが押されている CMP AL,0x1E ;上のCPM命令によってキャリーフラブが変化している。 ;同じならZFが1,CFが0になっている ;もしそうなら、文字表示ルーチンをコールする JE APRINT CMP AL,0x30 ;Bが押されている JE BPRINT CMP AL,0x2E ;Cが押されている JE CPRINT CMP AL,0x20 ;Dが押されている JE DPRINT CMP AL,0x12 ;Eが押されている JE EPRINT CMP AL,0x21 ;Fが押されている JE FPRINT CMP AL,0x22 ;Gが押されている JE GPRINT CMP AL,0x23 ;Hが押されている JE HPRINT CMP AL,0x17 ;Iが押されている JE IPRINT CMP AL,0x24 ;Jが押されている JE JPRINT CMP AL,0x25 ;Kが押されている JE KPRINT CMP AL,0x26 ;Lが押されている JE LPRINT CMP AL,0x32 ;Mが押されている JE MPRINT CMP AL,0x31 ;Nが押されている JE NPRINT CMP AL,0x18 ;Oが押されている JE OPRINT CMP AL,0x19 ;Pが押されている JE PPRINT CMP AL,0x10 ;Qが押されている JE QPRINT CMP AL,0x13 ;Rが押されている JE RPRINT CMP AL,0x1F ;Sが押されている JE SPRINT CMP AL,0x14 ;Tが押されている JE TPRINT CMP AL,0x16 ;Uが押されている JE UPRINT CMP AL,0x2F ;Vが押されている JE VPRINT CMP AL,0x11 ;Wが押されている JE WPRINT CMP AL,0x2D ;Xが押されている JE XPRINT CMP AL,0x15 ;Yが押されている JE YPRINT CMP AL,0x2C ;Zが押されている JE ZPRINT ;ENTER キー CMP AL,0x1C ;Zが押されている JE ENTERPRINT ;そうでなかったら、割り込みから戻る JMP INTEND ;文字ごとにコードをセットする APRINT: MOV AL,0x41 JMP MOJIPRINT BPRINT: MOV AL,0x42 JMP MOJIPRINT CPRINT: MOV AL,0x43 JMP MOJIPRINT DPRINT: MOV AL,0x44 JMP MOJIPRINT EPRINT: MOV AL,0x45 JMP MOJIPRINT FPRINT: MOV AL,0x46 JMP MOJIPRINT GPRINT: MOV AL,0x47 JMP MOJIPRINT HPRINT: MOV AL,0x48 JMP MOJIPRINT IPRINT: MOV AL,0x49 JMP MOJIPRINT JPRINT: MOV AL,0x4A JMP MOJIPRINT KPRINT: MOV AL,0x4B JMP MOJIPRINT LPRINT: MOV AL,0x4C JMP MOJIPRINT MPRINT: MOV AL,0x4D JMP MOJIPRINT NPRINT: MOV AL,0x4E JMP MOJIPRINT OPRINT: MOV AL,0x4F JMP MOJIPRINT PPRINT: MOV AL,0x50 JMP MOJIPRINT QPRINT: MOV AL,0x51 JMP MOJIPRINT RPRINT: MOV AL,0x52 JMP MOJIPRINT SPRINT: MOV AL,0x53 JMP MOJIPRINT TPRINT: MOV AL,0x54 JMP MOJIPRINT UPRINT: MOV AL,0x55 JMP MOJIPRINT VPRINT: MOV AL,0x56 JMP MOJIPRINT WPRINT: MOV AL,0x57 JMP MOJIPRINT XPRINT: MOV AL,0x58 JMP MOJIPRINT YPRINT: MOV AL,0x59 JMP MOJIPRINT ZPRINT: MOV AL,0x5A JMP MOJIPRINT ;文字を表示するルーチン MOJIPRINT: MOV AH,0x0e INT 0x10 JMP INTEND ;割り込み後は、この処理をしないと戻れない INTEND: MOV AL,0x01 ADD AL,0x60 MOV DX,0x20 OUT DX,AL IRET ENTERPRINT: ;現在のカーソルの位置を取得(Y座標のみ) MOV BH,0x0 MOV AH,0x03 INT 0x10 INC DH ;上で取得した行位置+1 CMP DH,0x19 ;もし、最下行だったらロールアップ JE ENTERPRINTLUP ;そうじゃなかったら、普通にカーソル移動 JMP ENTERPRINTNML ENTERPRINTLUP: ;BIOSでロールアップ。まず、ロールアップをする MOV AL,0x01 ;スクロールさせる行数。 MOV BH,0x0F ;スクロールさせて、開いたところの色 MOV CH,0x0 ;開始の行位置 MOV CL,0x0 ;開始の列位置 MOV DH,0x18 ;一番下の行位置。(25行) MOV DL,0x4F ;一番右の列位置。(80文字) MOV AH,0x06 INT 0x10 ;カーソルを最下行にセット MOV DH,0x18 JMP ENTERPRINTNML ENTERPRINTNML ;BIOSでカーソル位置を設定 MOV AH,0x02 MOV BH,0x0 MOV DL,0 INT 0x10 CALL PROMPTPRINT JMP INTEND PROMPTPRINT: ;BIOSコールで文字列を表示 MOV AH,0x13 MOV AL,0x01 MOV BH,0x0 MOV BL,0x0F MOV CX,0x07 ;本来はここで、DLとDHで座標を指定するが、これは変わらないので ;いらないと思う MOV BP,pmsg INT 0x10 RET ;プロンプトの文字列 pmsg DB "THEBBL>" ;----------------------------------------------------- ;---- これがないと、暴走しちゃうぞ! ------------- ;----------------------------------------------------- ;MS-DOS終了 INT 0x20