; ; млллллллм мллллллллм млллллллм ;оллллп пп плллммм пп олллл пллн ;олллн лпллл пплллм ллллппллм ;оллллм мллл олллм мллл олллл мллл ; плллллллпл пллллллллп плллллллп ; ; ;;; Authors ;;; Gustavo Sverzut Barbieri ;;; Ivens Prates Telles Alves ;;; ; References: ; Randall Hyde, "Art of Assembly Programming". ;NASM-IDE ASM Assistant Assembler Project File [BITS 16] ;Set code generation to 16 bit mode [ORG 0x0100] ;Set code start address to 0100h [SEGMENT .text] ;Main code segment mov ah, 1bh ; ah = bg | fg mov al, 'А' ; al = char call FillScreen ; fill the screen with char in al, color in ah call PrintAuthors call DrawKeys ; draw the piano's keyboard call AssignIntFunction FooLoop: cmp [FlagQuit], byte(1) jne Continues jmp Quit Continues: jmp FooLoop Quit: ;; Exit call RestoreIntFunction mov ah, 07h ; ah = bg | fg mov al, ' ' ; al = char call FillScreen ; fill the screen with char in al, color in ah call StopSound ; stops the sound int 20h ; return control to MS-DOS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Sound Functions: ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Play: Play the sound accordingly to KeysPressed ; Parameters: ; - None ; Return: ; - None Play: push ax push bx cli ; no ints inc byte [cs:PlayPos] cmp [cs:KeysPressed], word(0) jne Play_S call InitSound mov [cs:PlayPlayed], byte 0 ; flag to mark we played something Play_S: ;; is S pressed? mov ax, [cs:KeysPressed] or ax, 1111111111111110b cmp ax, 1111111111111111b jne Play_N_S ; no, jump to next possibility cmp [cs:PlayPos], byte 1 jg Play_E cmp [cs:PlayPlayed], byte 0 jne Play_E call K_S_Pressed ; yes, show key pressed and play sound inc byte [cs:PlayPlayed] jmp Play_E Play_N_S: call K_S_Released Play_E: ;; is E pressed? mov ax, [cs:KeysPressed] or ax, 1111111111111101b cmp ax, 1111111111111111b jne Play_N_E ; no, jump to next possibility cmp [cs:PlayPos], byte 2 jg Play_D cmp [cs:PlayPlayed], byte 0 jne Play_D call K_E_Pressed ; yes, show key pressed and play sound inc byte [cs:PlayPlayed] jmp Play_D Play_N_E: call K_E_Released Play_D: ;; is D pressed? mov ax, [cs:KeysPressed] or ax, 1111111111111011b cmp ax, 1111111111111111b jne Play_N_D ; no, jump to next possibility cmp [cs:PlayPos], byte 3 jg Play_R cmp [cs:PlayPlayed], byte 0 jne Play_R call K_D_Pressed ; yes, show key pressed and play sound inc byte [cs:PlayPlayed] jmp Play_R Play_N_D: call K_D_Released Play_R: ;; is R pressed? mov ax, [cs:KeysPressed] or ax, 1111111111110111b cmp ax, 1111111111111111b jne Play_N_R ; no, jump to next possibility cmp [cs:PlayPos], byte 4 jg Play_F cmp [cs:PlayPlayed], byte 0 jne Play_F call K_R_Pressed ; yes, show key pressed and play sound inc byte [cs:PlayPlayed] jmp Play_F Play_N_R: call K_R_Released Play_F: ;; is F pressed? mov ax, [cs:KeysPressed] or ax, 1111111111101111b cmp ax, 1111111111111111b jne Play_N_F ; no, jump to next possibility cmp [cs:PlayPos], byte 5 jg Play_G cmp [cs:PlayPlayed], byte 0 jne Play_G call K_F_Pressed ; yes, show key pressed and play sound inc byte [cs:PlayPlayed] jmp Play_G Play_N_F: call K_F_Released Play_G: ;; is G pressed? mov ax, [cs:KeysPressed] or ax, 1111111111011111b cmp ax, 1111111111111111b jne Play_N_G ; no, jump to next possibility cmp [cs:PlayPos], byte 6 jg Play_Y cmp [cs:PlayPlayed], byte 0 jne Play_Y call K_G_Pressed ; yes, show key pressed and play sound inc byte [cs:PlayPlayed] jmp Play_Y Play_N_G: call K_G_Released Play_Y: ;; is Y pressed? mov ax, [cs:KeysPressed] or ax, 1111111110111111b cmp ax, 1111111111111111b jne Play_N_Y ; no, jump to next possibility cmp [cs:PlayPos], byte 7 jg Play_H cmp [cs:PlayPlayed], byte 0 jne Play_H call K_Y_Pressed ; yes, show key pressed and play sound inc byte [cs:PlayPlayed] jmp Play_H Play_N_Y: call K_Y_Released Play_H: ;; is H pressed? mov ax, [cs:KeysPressed] or ax, 1111111101111111b cmp ax, 1111111111111111b jne Play_N_H ; no, jump to next possibility cmp [cs:PlayPos], byte 8 jg Play_U cmp [cs:PlayPlayed], byte 0 jne Play_U call K_H_Pressed ; yes, show key pressed and play sound inc byte [cs:PlayPlayed] jmp Play_U Play_N_H: call K_H_Released Play_U: ;; is U pressed? mov ax, [cs:KeysPressed] or ax, 1111111011111111b cmp ax, 1111111111111111b jne Play_N_U ; no, jump to next possibility cmp [cs:PlayPos], byte 9 jg Play_J cmp [cs:PlayPlayed], byte 0 jne Play_J call K_U_Pressed ; yes, show key pressed and play sound inc byte [cs:PlayPlayed] jmp Play_J Play_N_U: call K_U_Released Play_J: ;; is J pressed? mov ax, [cs:KeysPressed] or ax, 1111110111111111b cmp ax, 1111111111111111b jne Play_N_J ; no, jump to next possibility cmp [cs:PlayPos], byte 10 jg Play_I cmp [cs:PlayPlayed], byte 0 jne Play_I call K_J_Pressed ; yes, show key pressed and play sound inc byte [cs:PlayPlayed] jmp Play_I Play_N_J: call K_J_Released Play_I: ;; is I pressed? mov ax, [cs:KeysPressed] or ax, 1111101111111111b cmp ax, 1111111111111111b jne Play_N_I ; no, jump to next possibility cmp [cs:PlayPos], byte 11 jg Play_K cmp [cs:PlayPlayed], byte 0 jne Play_K call K_I_Pressed ; yes, show key pressed and play sound inc byte [cs:PlayPlayed] jmp Play_K Play_N_I: call K_I_Released Play_K: ;; is K pressed? mov ax, [cs:KeysPressed] or ax, 1111011111111111b cmp ax, 1111111111111111b jne Play_N_K ; no cmp [cs:PlayPos], byte 12 jg Play_Terminate cmp [cs:PlayPlayed], byte 0 jne Play_Terminate call K_K_Pressed ; yes, show key pressed and play sound inc byte [cs:PlayPlayed] jmp Play_Terminate Play_N_K: call K_K_Released Play_Terminate cmp [cs:KeysPressed], word(0) jne Play_END ; call StopSound ; stops the sound Play_END: cmp [cs:PlayPos], byte 12 jle Play_END_1 mov [cs:PlayPos], byte 0 Play_END_1: cmp [cs:PlayPlayed], byte 0 jne Play_END_2 mov [cs:PlayPos], byte 0 Play_END_2: mov [cs:PlayPlayed], byte 0 sti ; ints again pop bx pop ax ret InitSound: ;; save parameters push ax ;; Activates the PC Speaker in al, 61h ; get data from 61h or al, 11b ; set bits 0 and 1 out 61h, al ; send data to 61h ;; Activates the PC Speaker Controller mov ax, 0b6h out 43h, ax ;; restore parameters pop ax ret ;;; PlaySound(ax): Play sound with counter in ax ; Parameters: ; - ax: counter (from frequency) you wanna play ; Return: ; None PlaySound: ;; Save parameters push ax out 42h, al ; -play the sound xchg ah, al ; - out 42h, al ; - ;; Restore parameters pop ax ret ;;; StopSound: stop playing sound ; Parameters: ; None ; Return: ; None StopSound: push ax ;; Deactivate the PC Speaker in al, 61h ; get data from 61h and al, 00b ; unset bits 0 and 1 out 61h, al ; send data to 61h pop ax ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Keyboard Functions: ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; AssignIntFunction: Assigns Keyboard interruption to KeyboarHandler function ; Parameters: ; - None ; Return ; - None AssignIntFunction: ; save parameters we will use push es push di push ax push bx push cx push dx cli ; no interrupts by now les di, [IntSegment] ; es = interruption segment ;; Keyboard ;; Save actual interruption value mov dx, [es:09h*4] mov cx, [es:09h*4+2] mov [Var_SaveInt1], dx mov [Var_SaveInt2], cx ;; Assign new values mov ax, cs mov bx, KeyboardHandler mov [es:09h*4], bx mov [es:09h*4+2], ax ;; Clock ;; Save actual interruption value mov dx, [es:1ch*4] mov cx, [es:1ch*4+2] mov [Var_SaveInt3], dx mov [Var_SaveInt4], cx ;; Assign new values mov ax, cs mov bx, ClockHandler mov [es:1ch*4], bx mov [es:1ch*4+2], ax sti ; now interrupts are available again ; restore parameters we will use pop dx pop cx pop bx pop ax pop di pop es ret ;;; RestoreIntFunction: restore the previous assigned interruption ; Parameters: ; - None ; Return ; - None RestoreIntFunction: ;; save values push es push ax push cx push dx cli ; no ints ;; Keyboard ;; retore interrupt xor ax,ax mov es, ax mov dx, [Var_SaveInt1] mov cx, [Var_SaveInt2] mov [es:09h*4], dx mov [es:09h*4+2], cx ;; Clock ;; retore interrupt xor ax,ax mov es, ax mov dx, [Var_SaveInt3] mov cx, [Var_SaveInt4] mov [es:1ch*4], dx mov [es:1ch*4+2], cx sti ; ints agains ;; restore values pop dx pop cx pop ax pop es ret ;;; KeyboarHandler: ; Parameters: ; - None ; Return ; - None KeyboardHandler: push ax ;; Get key read in al, 60h call CheckKeys call KeyboardFree pop ax iret ;;; ClockHandler: ; Parameters: ; - None ; Return ; - None ClockHandler: call Play ; play sounds iret ;;; KeyboarFree: free the keyboard to receive more keys ; Parameters: ; - None ; Return ; - None KeyboardFree: push ax ; save ax, we will modify it ;; Say we want more keys mov al, 20h out 20h, al pop ax ; restore it ret ;;; CheckKeys(ax): check for keys pressed ; Parameters: ; - ax: al must contain the key pressed ; Return ; - ax: 1= Exit, 0= continues the execution CheckKeys: cli ; No interrupts by now ;; What key was pressed? ;; ESC? cmp al, 1 ; ESC Pressed je K_ESC_Pressed cmp al, 129 ; ESC Released je K_ESC_Released jmp CMP_KEYCODES K_ESC_Released: K_ESC_Pressed: xor ax, ax inc ax ; ax = 1 -> Quit the program jmp K_THE_END CMP_KEYCODES: ;; S ? cmp al, 31 ; S Pressed jne N_K_S_P or [cs:KeysPressed], word(0000000000000001b) jmp K_END_NO_QUIT N_K_S_P: cmp al, 159 ; S Released jne N_K_S_R and [cs:KeysPressed], word(1111111111111110b) jmp K_END_NO_QUIT N_K_S_R: ;; E ? cmp al, 18 ; E Pressed jne N_K_E_P or [cs:KeysPressed], word(0000000000000010b) jmp K_END_NO_QUIT N_K_E_P: cmp al, 146 ; E Released jne N_K_E_R and [cs:KeysPressed], word(1111111111111101b) jmp K_END_NO_QUIT N_K_E_R: ;; D ? cmp al, 32 ; D Pressed jne N_K_D_P or [cs:KeysPressed], word(0000000000000100b) jmp K_END_NO_QUIT N_K_D_P: cmp al, 160 ; D Released jne N_K_D_R and [cs:KeysPressed], word(1111111111111011b) jmp K_END_NO_QUIT N_K_D_R: ;; R ? cmp al, 19 ; R Pressed jne N_K_R_P or [cs:KeysPressed], word(0000000000001000b) jmp K_END_NO_QUIT N_K_R_P: cmp al, 147 ; R Released jne N_K_R_R and [cs:KeysPressed], word(1111111111110111b) jmp K_END_NO_QUIT N_K_R_R: ;; F ? cmp al, 33 ; F Pressed jne N_K_F_P or [cs:KeysPressed], word(0000000000010000b) jmp K_END_NO_QUIT N_K_F_P: cmp al, 161 ; F Released jne N_K_F_R and [cs:KeysPressed], word(1111111111101111b) jmp K_END_NO_QUIT N_K_F_R: ;; G ? cmp al, 34 ; G Pressed jne N_K_G_P or [cs:KeysPressed], word(0000000000100000b) jmp K_END_NO_QUIT N_K_G_P: cmp al, 162 ; G Released jne N_K_G_R and [cs:KeysPressed], word(1111111111011111b) jmp K_END_NO_QUIT N_K_G_R: ;; Y ? cmp al, 21 ; Y Pressed jne N_K_Y_P or [cs:KeysPressed], word(0000000001000000b) jmp K_END_NO_QUIT N_K_Y_P: cmp al, 149 ; Y Released jne N_K_Y_R and [cs:KeysPressed], word(1111111110111111b) jmp K_END_NO_QUIT N_K_Y_R: ;; H ? cmp al, 35 ; H Pressed jne N_K_H_P or [cs:KeysPressed], word(0000000010000000b) jmp K_END_NO_QUIT N_K_H_P: cmp al, 163 ; H Released jne N_K_H_R and [cs:KeysPressed], word(1111111101111111b) jmp K_END_NO_QUIT N_K_H_R: ;; U ? cmp al, 22 ; U Pressed jne N_K_U_P or [cs:KeysPressed], word(0000000100000000b) jmp K_END_NO_QUIT N_K_U_P: cmp al, 150 ; U Released jne N_K_U_R and [cs:KeysPressed], word(1111111011111111b) jmp K_END_NO_QUIT N_K_U_R: ;; J ? cmp al, 36 ; J Pressed jne N_K_J_P or [cs:KeysPressed], word(0000001000000000b) jmp K_END_NO_QUIT N_K_J_P: cmp al, 164 ; J Released jne N_K_J_R and [cs:KeysPressed], word(1111110111111111b) jmp K_END_NO_QUIT N_K_J_R: ;; I ? cmp al, 23 ; I Pressed jne N_K_I_P or [cs:KeysPressed], word(0000010000000000b) jmp K_END_NO_QUIT N_K_I_P: cmp al, 151 ; I Released jne N_K_I_R and [cs:KeysPressed], word(1111101111111111b) jmp K_END_NO_QUIT N_K_I_R: ;; K ? cmp al, 37 ; K Pressed jne N_K_K_P or [cs:KeysPressed], word(0000100000000000b) jmp K_END_NO_QUIT N_K_K_P: cmp al, 165 ; K Released jne N_K_K_R and [cs:KeysPressed], word(1111011111111111b) jmp K_END_NO_QUIT N_K_K_R: K_END_NO_QUIT: xor ax, ax ; ax=0 -> Don't quit the program K_THE_END: sti ; now interrupts are avaiable again mov [FlagQuit], al ret ;;; S K_S_Pressed: push ax push bx ;; play the sound mov ax, 2274 call PlaySound ;; show the key is pressed mov ax, 0 mov bh, 4Fh ; bh = bg | fg mov bl, 's' ; bl = char call DrawWhiteKeyHole pop bx pop ax ret K_S_Released: push ax push bx ;; show the key is released mov ax, 0 mov bh, 70h ; bh = bg | fg mov bl, 's' ; bl = char call DrawWhiteKeyHole pop bx pop ax ret ;;; E K_E_Pressed: push ax push bx ;; play the sound mov ax, 2147 call PlaySound ;; show the key is pressed mov ax, 0 mov bh, 1Fh ; bh = bg | fg mov bl, 'e' ; bl = char call DrawBlackKey pop bx pop ax ret K_E_Released: push ax push bx ;; show the key is released mov ax, 0 mov bh, 0Fh ; bh = bg | fg mov bl, 'e' ; bl = char call DrawBlackKey pop bx pop ax ret ;;; D K_D_Pressed: push ax push bx ;; play the sound mov ax, 2030 call PlaySound ;; show the key is pressed mov ax, 1 mov bh, 4Fh ; bh = bg | fg mov bl, 'd' ; bl = char call DrawWhiteKeyHole pop bx pop ax ret K_D_Released: push ax push bx ;; show the key is released mov ax, 1 mov bh, 70h ; bh = bg | fg mov bl, 'd' ; bl = char call DrawWhiteKeyHole pop bx pop ax ret ;;; R K_R_Pressed: push ax push bx ;; play the sound mov ax, 1916 call PlaySound ;; show the key is pressed mov ax, 1 mov bh, 1Fh ; bh = bg | fg mov bl, 'r' ; bl = char call DrawBlackKey pop bx pop ax ret K_R_Released: push ax push bx ;; show the key is released mov ax, 1 mov bh, 0Fh ; bh = bg | fg mov bl, 'r' ; bl = char call DrawBlackKey pop bx pop ax ret ;;; F K_F_Pressed: push ax push bx ;; play the sound mov ax, 1808 call PlaySound ;; show the key is pressed mov ax, 2 mov bh, 4Fh ; bh = bg | fg mov bl, 'f' ; bl = char call DrawWhiteKey pop bx pop ax ret K_F_Released: push ax push bx ;; show the key is released mov ax, 2 mov bh, 70h ; bh = bg | fg mov bl, 'f' ; bl = char call DrawWhiteKey pop bx pop ax ret ;;; G K_G_Pressed: push ax push bx ;; play the sound mov ax, 1707 call PlaySound ;; show the key is pressed mov ax, 3 mov bh, 4Fh ; bh = bg | fg mov bl, 'g' ; bl = char call DrawWhiteKeyHole pop bx pop ax ret K_G_Released: push ax push bx ;; show the key is released mov ax, 3 mov bh, 70h ; bh = bg | fg mov bl, 'g' ; bl = char call DrawWhiteKeyHole pop bx pop ax ret ;;; Y K_Y_Pressed: push ax push bx ;; play the sound mov ax, 1610 call PlaySound ;; show the key is pressed mov ax, 3 mov bh, 1Fh ; bh = bg | fg mov bl, 'y' ; bl = char call DrawBlackKey pop bx pop ax ret K_Y_Released: push ax push bx ;; show the key is released mov ax, 3 mov bh, 0Fh ; bh = bg | fg mov bl, 'y' ; bl = char call DrawBlackKey pop bx pop ax ret ;;; H K_H_Pressed: push ax push bx ;; play the sound mov ax, 1520 call PlaySound ;; show the key is pressed mov ax, 4 mov bh, 4Fh ; bh = bg | fg mov bl, 'h' ; bl = char call DrawWhiteKeyHole pop bx pop ax ret K_H_Released: push ax push bx ;; show the key is released mov ax, 4 mov bh, 70h ; bh = bg | fg mov bl, 'h' ; bl = char call DrawWhiteKeyHole pop bx pop ax ret ;;; U K_U_Pressed: push ax push bx ;; play the sound mov ax, 1436 call PlaySound ;; show the key is pressed mov ax, 4 mov bh, 1Fh ; bh = bg | fg mov bl, 'u' ; bl = char call DrawBlackKey pop bx pop ax ret K_U_Released: push ax push bx ;; show the key is released mov ax, 4 mov bh, 0Fh ; bh = bg | fg mov bl, 'u' ; bl = char call DrawBlackKey pop bx pop ax ret ;;; J K_J_Pressed: push ax push bx ;; play the sound mov ax, 1354 call PlaySound ;; show the key is pressed mov ax, 5 mov bh, 4Fh ; bh = bg | fg mov bl, 'j' ; bl = char call DrawWhiteKeyHole pop bx pop ax ret K_J_Released: push ax push bx ;; show the key is released mov ax, 5 mov bh, 70h ; bh = bg | fg mov bl, 'j' ; bl = char call DrawWhiteKeyHole pop bx pop ax ret ;;; I K_I_Pressed: push ax push bx ;; play the sound mov ax, 1278 call PlaySound ;; show the key is pressed mov ax, 5 mov bh, 1Fh ; bh = bg | fg mov bl, 'i' ; bl = char call DrawBlackKey pop bx pop ax ret K_I_Released: push ax push bx ;; show the key is released mov ax, 5 mov bh, 0Fh ; bh = bg | fg mov bl, 'i' ; bl = char call DrawBlackKey pop bx pop ax ret ;;; K K_K_Pressed: push ax push bx ;; play the sound mov ax, 1206 call PlaySound ;; show the key is pressed mov ax, 6 mov bh, 4Fh ; bh = bg | fg mov bl, 'k' ; bl = char call DrawWhiteKey pop bx pop ax ret K_K_Released: push ax push bx ;; show the key is released mov ax, 6 mov bh, 70h ; bh = bg | fg mov bl, 'k' ; bl = char call DrawWhiteKey pop bx pop ax ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Video Functions: ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; DrawKeys: Draw all the White and Black keys ; Parameters: ; None ; Return: ; None DrawKeys: mov ax, 0 mov bh, 70h ; bh = bg | fg mov bl, 's' ; bl = char call DrawWhiteKeyHole mov ax, 0 mov bh, 0Fh ; bh = bg | fg mov bl, 'e' ; bl = char call DrawBlackKey mov ax, 1 mov bh, 70h ; bh = bg | fg mov bl, 'd' ; bl = char call DrawWhiteKeyHole mov ax, 1 mov bh, 0Fh ; bh = bg | fg mov bl, 'r' ; bl = char call DrawBlackKey mov ax, 2 mov bh, 70h ; bh = bg | fg mov bl, 'f' ; bl = char call DrawWhiteKey mov ax, 3 mov bh, 70h ; bh = bg | fg mov bl, 'g' ; bl = char call DrawWhiteKeyHole mov ax, 3 mov bh, 0Fh ; bh = bg | fg mov bl, 'y' ; bl = char call DrawBlackKey mov ax, 4 mov bh, 70h ; bh = bg | fg mov bl, 'h' ; bl = char call DrawWhiteKeyHole mov ax, 4 mov bh, 0Fh ; bh = bg | fg mov bl, 'u' ; bl = char call DrawBlackKey mov ax, 5 mov bh, 70h ; bh = bg | fg mov bl, 'j' ; bl = char call DrawWhiteKeyHole mov ax, 5 mov bh, 0Fh ; bh = bg | fg mov bl, 'i' ; bl = char call DrawBlackKey mov ax, 6 mov bh, 70h ; bh = bg | fg mov bl, 'k' ; bl = char call DrawWhiteKey ret ;;; FillScreen(ax): fill the screen with the given char ; Parameters: ; - ax: should contain color|char in ah|al respectively ; Return: ; None FillScreen: ; save parameters we will use push di push es push ax push bx ; Let es be the Video Segment les di, [cs:VideoSegment] ; video memory address: es = b800, di = 0000 xor bx, bx ; Main loop ( while (bx < screen_size) ) Loop_FillScreen: mov [es:bx], ax add bx, 2 cmp bx, 4000 jne Loop_FillScreen ; restore parameters we have used pop bx pop ax pop es pop di ret ;;; DrawWhiteKey(ax,bx) ; Parameters: ; - ax: posisition (0, 1, 2, 3, 4, 5, 6) ; - bx: color|char ; Return: ; None DrawWhiteKey: ; save parameters we will use push di push es push dx push cx push bx push ax ; Let es be the Video Segment les di, [cs:VideoSegment] ; video memory address: es = b800, di = 0000 mov ch, bh ; ch = bh (same attributes: fg/bg color) mov cl, ' ' ; cl = char (char used to draw the key) mov dx, bx ; dx = bx, we will use bx later mov bl, al ; xor ax,ax ; mov ax,12 ; key width '##### ' mul bl ; go to this key position mov bx, ax add bx, [cs:LeftSpace] push dx ; save, we'll use as counter to loop xor dx, dx ; zero ;; Loop: while (dx < 20) DrawWhiteKey_Loop1: mov [es:bx], cx ; draw mov [es:bx+2], cx ; draw mov [es:bx+4], cx ; draw mov [es:bx+6], cx ; draw mov [es:bx+8], cx ; draw add bx, [cs:LineSize] inc dx cmp dx,20 jne DrawWhiteKey_Loop1 pop dx ; restore, we've used it as counter to loop ;; Now, draw the key associated sub bx, [cs:LineSize] sub bx, [cs:LineSize] sub bx, [cs:LineSize] mov [es:bx+4], dx ; draw ; restore parameters we've used pop ax pop bx pop cx pop dx pop es pop di ret ;;; DrawWhiteKeyHole(ax,bx): draws white key with a hole on top right ; Parameters: ; - ax: posisition (0, 1, 2, 3, 4, 5, 6) ; - bx: color|char ; Return: ; None DrawWhiteKeyHole: ; save parameters we will use push di push es push dx push cx push bx push ax ; Let es be the Video Segment les di, [cs:VideoSegment] ; video memory address: es = b800, di = 0000 mov ch, bh ; ch = bh (same attributes: fg/bg color) mov cl, ' ' ; cl = char (char used to draw the key) mov dx, bx ; dx = bx, we will use bx later mov bl, al ; xor ax,ax ; mov ax,12 ; key width '##### ' mul bl ; go to this key position mov bx, ax add bx, [cs:LeftSpace] push dx ; save, we'll use as counter to loop xor dx, dx ; zero ;; Loop: while (dx < 20) DrawWhiteKeyHole_Loop1: mov [es:bx], cx ; draw mov [es:bx+2], cx ; draw mov [es:bx+4], cx ; draw add bx, [cs:LineSize] inc dx cmp dx,10 jne DrawWhiteKeyHole_Loop1 xor dx, dx DrawWhiteKeyHole_Loop2: mov [es:bx], cx ; draw mov [es:bx+2], cx ; draw mov [es:bx+4], cx ; draw mov [es:bx+6], cx ; draw mov [es:bx+8], cx ; draw add bx, [cs:LineSize] inc dx cmp dx,10 jne DrawWhiteKeyHole_Loop2 pop dx ; restore, we've used it as counter to loop ;; Now, draw the key associated sub bx, [cs:LineSize] sub bx, [cs:LineSize] sub bx, [cs:LineSize] mov [es:bx+4], dx ; draw ; restore parameters we've used pop ax pop bx pop cx pop dx pop es pop di ret ;;; DrawBlackKey(ax,bx) ; Parameters: ; - ax: posisition (0, 1, 2, 3, 4, 5, 6) ; - bx: color|char ; Return: ; None DrawBlackKey: ; save parameters we will use push di push es push dx push cx push bx push ax ; Let es be the Video Segment les di, [cs:VideoSegment] ; video memory address: es = b800, di = 0000 mov cx, 0b800h mov es, cx mov ch, bh ; ch = bh (same attributes: fg/bg color) mov cl, ' ' ; cl = char (char used to draw the key) mov dx, bx ; dx = bx, we will use bx later mov bl, al ; xor ax,ax ; mov ax,12 ; key width '##### ' mul bl ; go to this key position mov bx, ax add bx, [cs:LeftSpace] add bx, 6 ; after the left space, we need to skip 3 position from the White key push dx ; save, we'll use as counter to loop xor dx, dx ; zero ;; Loop: while (dx < 6) DrawBlackKey_Loop1: mov [es:bx], cx ; draw mov [es:bx+2], cx ; draw add bx, [cs:LineSize] inc dx cmp dx,10 jne DrawBlackKey_Loop1 pop dx ;; Now, draw the key associated sub bx, [cs:LineSize] sub bx, [cs:LineSize] sub bx, [cs:LineSize] mov [es:bx+2], dx ; draw ; restore parameters we've used pop ax pop bx pop cx pop dx pop es pop di ret PrintAuthors: mov ax, Author1 mov bx, 160*23 call PrintText mov bx, 160*24 mov ax, Author2 call PrintText ret PrintText: push si push ds push ax mov si, ax mov ax, cs mov ds, ax les di, [cs:VideoSegment] add di, bx mov ah, 1Fh PrintText_Loop1: lodsb stosw cmp al, 0 jne PrintText_Loop1 pop ax pop ds pop si ret [SEGMENT .data] ;Initialised data segment VideoSegment DD 0B8000000h ; Video memory segment IntSegment DD 000000000h ; Interrupts segment BiosSegment DD 000400000h ; BIOS segment LeftSpace DW 40; space (bytes) from left margin LineSize DW 160; bytes per line Var_SaveInt1 DW 0 ; will save old interrupt here to restore later Var_SaveInt2 DW 0 ; will save old interrupt here to restore later Var_SaveInt3 DW 0 ; will save old interrupt here to restore later Var_SaveInt4 DW 0 ; will save old interrupt here to restore later FlagQuit DB 0 ; we've to quit? KeysPressed DW 0000000000000000b ; keys we've pressed PlayPos DB 0 PlayPlayed DB 0 Author1 DB "Gustavo Sverzut Barbieri ",0 Author2 DB "Ivens Prates Telles Alves ",0