[合言][作] TSR program@Morris' Blog|PChome Online 人新台
2013-06-03 08:28:42| 人5,612| 回1 | 上一篇 | 下一篇

[合言][作] TSR program

0 收藏 0 0 站台


作要求:

  • Write a TSR program which uses the keyboard interrupt.
    一以interrupt作件的TSR(Terminate and Stay Resident)程式。
  • When a hot key (using ^ as hot key) is pressed, the TSR program writes your English name and student ID in the middle of the console.
    用“^”作的,按下去後在幕上示你的“英文名字和”。
  • Note: the TSR program must write your name and ID directly onto the video RAM of the console instead of using INT calls.
    提醒:TSR程式必直接字串料“控制面的位址”,而不是使用INT指令。(用了程式掉)












心得

次作的程序流程跟以往在撰的程式不一,保留一部分的程式片段於部,且在行的候行似於安的理程序, DOS 系的interrupt vector table 修改成跳到自己指定的程序片段,因此,所的程序被作中指令被,而在入,示於幕的指令,中入的程序行控制。
於早期的 DOS 有很多 interrupt vector table 的值是可以被修改的,了鼓早期的者在 MS-DOS 上面,因此允使用者行修改,但由於interrupt vector 有碰撞的可能,就生程序相容性的。在的 vector table 是被部分保以防止作系流程不正,也是防止病毒的一方式。
而在理入的 scan key ,可以照以下的址:
http://www.delorie.com/djgpp/doc/rbinter/it/06/0.html
次的程序流程稍微比麻,有判的 AND OR 布林算,了不大幅度修改程式,用展的方式理每一步。

清 push 指令 call proc 取得的念,由於入的是 reg16 因此的是 [bp+4]、[bp+6],又因是 near call,bp return_address(只有 ip)都是 2 bytes,所以第一位置在 [bp+4]。
在音理部分,於以下的址。
http://www.autoitscript.com/forum/topic/40848-beep-music-mario-bros-theme/


Values for keyboard make/break (scan) code: 01h Esc 31h N 02h 1 ! 32h M 03h 2 @ 33h , < 63h F16 04h 3 # 34h . > 64h F17 05h 4 $ 35h / ? 65h F18 06h 5 % 36h Right Shift 66h F19 07h 6 ^ 37h Grey* 67h F20 08h 7 & 38h Alt 68h F21 (Fn) [*] 09h 8 * 39h SpaceBar 69h F22 0Ah 9 ( 3Ah CapsLock 6Ah F23 0Bh 0 ) 3Bh F1 6Bh F24 0Ch - _ 3Ch F2 6Ch -- 0Dh = + 3Dh F3 6Dh EraseEOF 0Eh Backspace 3Eh F4 0Fh Tab 3Fh F5 6Fh Copy/Play 10h Q 40h F6 11h W 41h F7 12h E 42h F8 72h CrSel 13h R 43h F9 73h <delta> [*] 14h T 44h F10 74h ExSel 15h Y 45h NumLock 75h -- 16h U 46h ScrollLock 76h Clear 17h I 47h Home 77h [Note2] Joyst But1 18h O 48h UpArrow 78h [Note2] Joyst But2 19h P 49h PgUp 79h [Note2] Joyst Right 1Ah [ { 4Ah Grey- 7Ah [Note2] Joyst Left 1Bh ] } 4Bh LeftArrow 7Bh [Note2] Joyst Up 1Ch Enter 4Ch Keypad 5 7Ch [Note2] Joyst Down 1Dh Ctrl 4Dh RightArrow 7Dh [Note2] right mouse 1Eh A 4Eh Grey+ 7Eh [Note2] left mouse 1Fh S 4Fh End 20h D 50h DownArrow 21h F 51h PgDn 22h G 52h Ins 23h H 53h Del 24h J 54h SysReq ---non-key codes--- 25h K 55h [Note1] F11 00h kbd buffer full 26h L 56h left \| (102-key) 27h ; : 57h F11 AAh self-test complete 28h ' " 58h F12 E0h prefix code 29h ` ~ 59h [Note1] F15 E1h prefix code 2Ah Left Shift 5Ah PA1 EEh ECHO 2Bh \ | 5Bh F13 (LWin) F0h prefix code (key break) 2Ch Z 5Ch F14 (RWin) FAh ACK 2Dh X 5Dh F15 (Menu) FCh diag failure (MF-kbd) 2Eh C FDh diag failure (AT-kbd) 2Fh V FEh RESEND 30h B FFh kbd error/buffer full


程式明

基本上都是由 TSR.asm 主下去修改的,必了解 segment at 的指令是抓的位置。於 combination 的入合,取 keyboard flag 利用 bit mask 字抓出判。
而在理出的候,特要注意的位址,如果有加指定的 segment address,用正在行的程序的 cs, ds, ss,由於程序用到另一 segment address 入,因此的候要特注意。
由於 mov 指令有 mem, mem 的格式,因此需要多一部分去理。在示息的部分,定座的 base 是左上角,了不 counter 生的情去做理。而在的 RAM 中,是用 byte 去表示一格的示(印出字元+示性),因此每次印出的移是 2 bytes 位。
使用 wasd 上下控制一方向示 (^<)=)
字型撰 beep function, delay 理上不方便,有 int 指令去直接算差,如果要求是以秒位,可以用系去判,但如果在其以下 ms 位法表示,藉此使用一些 nop 去拖延。



TITLE TSR homework6 (TSR.asm)
; Write a TSR program which uses the keyboard interrupt.
; When a hot key (using ^ as hot key) is pressed, the TSR
; program writes your English name and student ID in the
; middle of the console.
; Note: the TSR program must write your name and ID directly
; onto the video RAM of the console instead of using INT calls.


intno      EQU 09h               ; keyboard interrupt number
center     EQU (80*13+40)*2     ; screen 80x25, two bytes for each cell
leftup    EQU (80*0+0)*2        ; left up side
six_key EQU 07h                ; scan code for 6 key
w_key    EQU    11h                ; scan code for w key
a_key    EQU    1eh                ; scan code for a key
s_key    EQU    1fh                ; scan code for s key
d_key    EQU    20h                ; scan code for d key
m_key    EQU 32h                ; scan code for m key
rt_shift    EQU 01h            ; right shift key: bit 0
lt_shift    EQU 02h            ; left shift key: bit 1

VRamText SEGMENT at 0b800h     ; screen ram memory
VRamText ENDS

codeseg SEGMENT PARA
    assume cs:codeseg, ds:codeseg, es:VRamText
   
    ORG    100h            ; this is a .com program. must be before main
start:                  ; start ENDS
    jmp setup           ; jump to TSR installation
; data block
lcounter      dw    0    ; pressed counter
scounter      dw    0    ; shift counter
ncounter      dw    0   ; shift next counter
shiftimg      db    '>' ; shift image character
old_interrupt dd    ?    ; DWORD(32bit) es:ip
msg              db    'Morris_100502205', '$'
msglen          equ     $-msg-1
musichz    WORD    2600, 796, 796, 796, 1686, 1592, 1592, 1592, 3373, 3183
WORD     3373, 3183, 3183, 6366, 1686, 1592, 1592, 1686, 1592, 1592
WORD     1686, 14857, 1418, 1502, 1418, 1263, 1418, 1592, 1787, 1686
WORD     1592, 1592, 1686, 1592, 1592, 1686, 1592, 1418, 1502, 1418
WORD     1263, 1, 1126, 1062, 843, 796, 1, 1686, 1592, 1592
WORD     1686, 1592, 1592, 1686, 1592, 1418, 1502, 1418, 1263, 1418
WORD     1592, 1787, 1893, 1787, 1592, 1418, 1592, 1787, 1893, 2125
WORD     1893, 1787, 1592, 1787, 1893, 2125, 2385, 2125, 1893, 1787
WORD     1893, 2125, 2527, 2385, 1, 3573, 3183, 3785, 2385, 2527
WORD     2677, 2836, 2527, 2385, 1418, 2527, 1418, 709, 2836, 3183
WORD     2836, 2527, 1592, 2836, 1592, 796, 3183, 3573, 3183, 2836
WORD     1787, 3005, 1787, 893, 3573, 3785, 4011, 3785, 1893, 1787
WORD     1592, 2836, 2527, 2385, 1418, 2527, 1418, 709, 2836, 3183
WORD     2836, 2527, 1592, 2836, 1592, 796, 3183, 3573, 3183, 2836
WORD     1787, 1893, 1787, 1686, 1592, 3183, 3183, 3183, 3183, 6366
WORD     6366, 6366, 6745, 6366, 6745, 6366, 6009, 5672, 5354, 5053
musicde WORD    200, 200, 200, 200, 200, 200, 200, 200, 200, 200
WORD     200, 200, 400, 400, 200, 200, 200, 200, 200, 200
WORD     200, 200, 200, 200, 200, 400, 200, 200, 200, 200
WORD     200, 200, 200, 200, 200, 200, 200, 200, 200, 200
WORD     400, 200, 10, 200, 10, 200, 200, 200, 200, 200
WORD     200, 200, 200, 200, 200, 200, 200, 200, 400, 200
WORD     200, 200, 200, 200, 200, 400, 200, 200, 200, 200
WORD     200, 200, 400, 200, 200, 200, 200, 200, 200, 400
WORD     200, 200, 200, 200, 400, 400, 200, 200, 200, 200
WORD     200, 200, 200, 200, 200, 200, 200, 200, 200, 200
WORD     200, 200, 200, 200, 200, 200, 200, 200, 200, 200
WORD     200, 200, 200, 200, 200, 200, 200, 200, 200, 400
WORD     400, 200, 200, 200, 200, 200, 200, 200, 200, 200
WORD     200, 200, 200, 200, 200, 200, 200, 200, 200, 200
WORD     200, 200, 200, 200, 200, 200, 200, 200, 200, 200
WORD     200, 200, 200, 200, 200, 200, 200, 200, 200, 200
; memory-resident code begins here
int_handler:
    pushf            ; save flags
    push    ax        ; save regs
    push    dx
    push    es
    push    cx
    push    di
    push    si
; point ES:DI to the DOS keyboard flag byte:
    mov        ax, 40h     ; DOS data segment is at 40h
    mov     es, ax   
    mov        di, 17h        ; location of keyboard flag
    mov        ah, es:[di]    ; copy keyboard flag into AH
; test for the LEFT_SHIFT and RIGHT_SHIFT keys:
    test    ah, rt_shift    ; right shift key held down??
    jnz        L1              ; yes: process
    test    ah, lt_shift    ; left shift key held down?
    jnz        L1                ; yes: process
    jmp        byPass            ; no LEFT_SHIFT or RIGHT_SHIFT: exit
; test if hot-key(^) pressed by (left/right)shift+6
L1:    in        al, 60h        ; 60h keyboard input port
    cmp        al, six_key    ; 6 key pressed?
    jnz        byPass  &bsp;     ; no: exit
; point ES:DI to the DOS screen RAM, DS:SI to the string address
; clear last time print
    sub        lcounter, 2*msglen    ; make clear using
    mov        ax, cs
    mov     ds, ax
    mov        ax,    VRamText
    mov        es, ax
    mov        ax, center
    add        ax, lcounter
    mov        di, ax    ; screen buffer offset
    lea        si, msg ; string address offset
; place the message into the video text buffer
    mov        cx, msglen
CL1:        ; run write into screen buffer
    mov        al, ' '        ; get character from string[si]
    mov        BYTE PTR es:[di], al    ; write into buffer[di]
    inc        di
    inc        di                        ; skip over the color attribute byte
    inc        si
    add        lcounter, 2
    loop     CL1
    sub        lcounter, 2*msglen
    add        lcounter, 2
   
    mov        ax, cs
    mov     ds, ax
    mov        ax,    VRamText
    mov        es, ax
    mov        ax, center
    add        ax, lcounter
    mov        di, ax    ; screen buffer offset
    lea        si, msg ; string address offset
; place the message into the video text buffer
    mov        cx, msglen
DP1:        ; run write into screen buffer
    mov        al, BYTE PTR [si]        ; get character from string[si]
    mov        BYTE PTR es:[di], al    ; write into buffer[di]
    inc        di
    inc        di                        ; skip over the color attribute byte
    inc        si
    add        lcounter, 2
    loop     DP1
    jmp        byPassEnd
byPass:        ; ignore unneeded input
; check w, a, s, d input
    in        al, 60h        ; 60h keyboard input port
    cmp        al, w_key    ; w key pressed?
    jz        wshift        ; yes: wshift
    cmp        al, a_key    ; a key pressed?
    jz        ashift        ; yes: ashift
    cmp        al, s_key    ; s key pressed?
    jz        sshift        ; yes: sshift
    cmp        al, d_key    ; d key pressed?
    jz        dshift        ; yes: dshift
    jmp        byPassEnd
wshift:
    mov        ax, scounter
    mov        ncounter, ax
    sub        ncounter, 80
    sub        ncounter, 80
    mov        shiftimg, '^'
    jmp        shiftpro
ashift:   
    mov        ax, scounter
    mov        ncounter, ax
    dec        ncounter
    dec        ncounter
    mov        shiftimg, '<'
    jmp        shiftpro
sshift:   
    mov        ax, scounter
    mov        ncounter, ax
    add        ncounter, 80
    add        ncounter, 80
    mov        shiftimg, '='
    jmp        shiftpro
dshift:   
    mov        ax, scounter
    mov        ncounter, ax
    add        ncounter, 1
    add        ncounter, 1
    mov        shiftimg, '>'
    jmp        shiftpro
; point ES:DI to the DOS screen RAM, DS:SI to the string address
shiftpro:
; clear last time print
    mov        ax, cs
    mov     ds, ax
    mov        ax,    VRamText
    mov        es, ax
    mov        ax, leftup
    add        ax, scounter
    mov        di, ax            ; screen buffer offset
    lea        si, shiftimg     ; string address offset
; place the message into the video text buffer
    mov        cx, 1
CSL1:        ; run write into screen buffer
    mov        al, ' '                    ; get character from string[si]
    mov        BYTE PTR es:[di], al    ; write into buffer[di]
    inc        di
    inc        di                        ; skip over the color attribute byte
    inc        si
    add        scounter, 2
    loop     CSL1
    sub        scounter, 2
;
    mov        ax, ncounter
    mov        scounter, ax
    mov        ax, cs
    mov     ds, ax
    mov        ax,    VRamText
    mov        es, ax
    mov        ax, leftup
    add        ax, scounter
    mov        di, ax            ; screen buffer offset
    lea        si, shiftimg     ; string address offset
; place the message into the video text buffer
    mov        cx, 1
SL1:        ; run write into screen buffer
    mov        al, BYTE PTR [si]        ; get character from string[si]
    mov        BYTE PTR es:[di], al    ; write into buffer[di]
    inc        di
    inc        di                        ; skip over the color attribute byte
    inc        si
    add        scounter, 2
    loop     SL1
    sub        scounter, 2
byPassEnd:
    in        al, 60h        ; 60h keyboard input port
    cmp        al, m_key    ; m key pressed?
    jnz        byPassEnd2    ; no: exit
; music play
    mov        ax, cs
    mov     ds, ax
    mov        cx, 160        ; music size
    lea        di, musichz
    lea        si, musicde
loops:
    mov        ax, [di]
    push    ax
    mov        ax, [si]
    push    ax
    call    beep
    inc        di
    inc        di
    inc        si
    inc        si       
    mov        ax, 1        ; make delay between music note
    push    ax
    mov        ax, 200
    push    ax
    call    beep
    loop    loops
byPassEnd2:
    pop        si        ; restore regs
    pop        di
    pop        cx
    pop        es
    pop        dx
    pop        ax
    popf            ; restore flags
    sti        ; set interrupt flag
    jmp        cs:old_interrupt    ; jump to INT routine
                                ; jmp cs:[old_interrupt] is the same, and by this method far call
    align    dword     ; because memory cell bound, DWORD will be faster.
beep PROC ; push hz[bp+6], push delay[bp+4]
    push    bp
    mov        bp, sp
    push    cx
    push    ax
   
    mov     al, 10110110b     ; out control byte
    out     43h, al           ;     to port 43h
    mov     ax, [bp+6]        ; Frequency = 1.19 MHz/ ???hz
    out     42h,al             ; out low-byte of frequency divider
    mov     al, ah
    out     42h, al         ; out high-byte of frequence divider
; on-off-on
    in         al, 61h
    or      al, 00000011b     ;on bit0 and bit 1
    out     61h, al        
    and     al, 11111100b   ; off bit0 and bit 1
    out     61h, al         ;  of port 61h        
    or      al,    00000011b     ;on bit0 and bit 1
    out     61h, al
; delay ??? ms
    mov        cx, [bp+4]        ; get delay parameter
delay_loop:
    push    cx
    mov        cx, 300h        ; this value will response different computer clock rate.
loop2:
    and        ax, ax           ; nop
    loop     loop2
    pop        cx
    loop     delay_loop
; close
    in         al, 61h
    and     al, 11111100b        ; off bit0 and bit 1
    out     61h, al              ;  of port 61h      
    pop        ax
    pop        cx
    pop        bp
    ret        4                ; clear stack 2+2 bytes
beep ENDP
end_ISR label byte
setup:
;    mov ax, cs        ; not necessary for .com program
;   mov ds, ax        ; code segment already correct.
    mov        ah, 35h
    mov        al, intno ; get INT 9 vector
    int        21h
    mov        WORD PTR old_interrupt, bx   ; save INT 9 vector
    mov        WORD PTR old_interrupt+2, es
    cli        ; clear interrupt flag, disables external interrupts
    mov        ah, 25h      ; set interrupt vector, INT 9 with ds:dx
    mov        al, intno ;
    mov        dx, OFFSET int_handler
    int        21h
    sti        ; set interrupt flag
   
    mov        ah, 09h      ; write a $-terminated string to standard output
    mov        dx, OFFSET msg
    int        21h          ; only to show something.
   
    mov        ax, 3100h  ; terminate and stay resodent
    mov        dx, OFFSET end_ISR ; point to end of resident code
    int        21h          ; dx must be the program size in bytes. execute MS-DOS function
codeseg ENDS
END start

台: Morris
人(5,612) | 回(1)| 推 (0)| 收藏 (0)|
全站分: 不分 | 人分: []合言 |
此分上一篇:[合言][作] Real-mode program
真不知道你到底是想弟妹是想害弟妹.....
2014-06-24 23:29:35
是 (若未登入"人新台"看不到回覆唷!)
* 入:
入片中算式的果(可能0) 
(有*必填)
TOP
全文
ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86