.MODEL SMALL .STACK 200h .386 .DATA CR EQU 0DH LF EQU 0AH PULALINHA DB CR,LF MOLD1 DB 0C9H,55 DUP (0CDH),0BBH,CR,LF,'$' MOLD2 DB 0BAH,13 DUP (' '),0B3H,41 DUP (' '),0BAH,CR,LF,'$' MOLD3 DB 0C8H,55 DUP (0CDH),0BCH,'$' MOLD4 DB 13 DUP (0C4H),'$' TITULO DB 'CALCULADORA$' TIT2 DB 'Mensagens:$' TIT3 DB 'Erros:$' MSG1 DB '<- Digite o 1o numero$' MSG2 DB '<- Digite o 2o numero$' MSG3 DB '<- Digite o sinal (+,-,*,/,b,h)$' MSG4 DB '#- RESULTADO$' MSG5 DB '<- Deseja realizar outra operacao?$' ERRO DB 'Erro$' ERRO1 DB 'Erro: Sinal invalido$' ERRO2 DB 'Erro: Numero invalido$' NUM1 DW ? NUM2 DW ? SINAL DB ? ;DATA DA ANIMACAO INICIAL BufferX EQU 320 BufferY EQU 104 Buffer DB BufferX * BufferY DUP (?) Seed DW 3749h INCLUDE PALETTE.DAT .CODE ;========================================================== ;ANIMACAO DO FOGO ;========================================================== InitializeMCGA PROC MOV AX, 0A000h MOV ES, AX ; ES now points to the VGA MOV AH, 00H ; Set video mode MOV AL, 13H ; Mode 13h INT 10H ; We are now in 320x200x256 RET InitializeMCGA ENDP SetUpPalette PROC MOV SI, OFFSET Palette ; SI now points to the palette MOV CX, 768 ; Prepare for 768 OUTs MOV DX, 03C8H ; Palette WRITE register XOR AL, AL ; Start at color 0 CLI ; Disable interrupts OUT DX, AL ; Send value CLD ; Forward direction INC DX ; Now use palette DATA register REP OUTSB ; 768 multiple OUTs STI ; Enable interrupts RET SetupPalette ENDP Random PROC MOV AX, Seed ; Move the seed value into AX MOV DX, 8405H ; Move 8405H into DX MUL DX ; Put 8405H x Seed into DX:AX INC AX ; Increment AX MOV Seed, AX ; We have a new seed RET Random ENDP DrawScreen PROC MOV SI, OFFSET Buffer ; Point SI to the start of the buffer XOR DI, DI ; Start drawing at 0, 0 MOV BX, BufferY - 4 ; Miss the last four lines from the ; buffer. These lines will not look ; fire-like at all Row: MOV CX, BufferX SHR 1 ; 160 WORDS REP MOVSW ; Move them SUB SI, 320 ; Go back to the start of the array row MOV CX, BufferX SHR 1 ; 160 WORDS REP MOVSW ; Move them DEC BX ; Decrease the number of VGA rows left JNZ Row ; Are we finished? RET DrawScreen ENDP AveragePixels PROC MOV CX, BufferX * BufferY - BufferX * 2 ; Alter all of the buffer, ; except for the first row and ; last row MOV SI, OFFSET Buffer + 320 ; Start from the second row Alter: XOR AX, AX ; Zero out AX MOV AL, DS:[SI] ; Get the value of the current pixel ADD AL, DS:[SI+1] ; Get the value of pixel to the right ADC AH, 0 ADD AL, DS:[SI-1] ; Get the value of pixel to the left ADC AH, 0 ADD AL, DS:[SI+BufferX] ; Get the value of the pixel underneath ADC AH, 0 SHR AX, 2 ; Divide the total by four JZ NextPixel ; Is the result zero? DEC AX ; No, so decrement it by one NextPixel: MOV DS:[SI-BufferX], AL ; Put the new value into the array INC SI ; Next pixel DEC CX ; One less to do JNZ Alter ; Have we done them all? RET AveragePixels ENDP TextMode PROC MOV AH, 00H ; Set video mode MOV AL, 03H ; Mode 03h INT 10H ; Enter 80x25x16 mode RET TextMode ENDP ;========================================================== ;MAIN ;========================================================== MAIN PROC MOV AX, @DATA MOV DS, AX CALL InitializeMCGA CALL SetUpPalette MainLoop: CALL AveragePixels MOV SI, OFFSET Buffer + BufferX * BufferY - BufferX SHL 1 MOV CX, BufferX SHL 1 BottomLine: CALL Random MOV DS:[SI], DL INC SI DEC CX JNZ BottomLine CALL DrawScreen MOV AH, 01H INT 16H JZ MainLoop MOV AH, 00H INT 16H ; MOV AX,@DATA ; MOV DS,AX MOV AH,0 ;setando o modo de video 3 MOV AL,3 INT 10H CALL JANELA MOV AH,2 ;LE NUM1 MOV DH,3 MOV DL,15 XOR BH,BH INT 10H MOV AH,9 LEA DX,MSG1 INT 21H MOV AH,2 ;vai para o visor ler o numero 1 MOV DH,3 MOV DL,1 XOR BH,BH INT 10H CALL ENTDEC ;chama leitura 1 MOV NUM1,AX MOV AH,2 ;LE NUM2 MOV DH,4 MOV DL,15 XOR BH,BH INT 10H MOV AH,9 LEA DX,MSG2 INT 21H MOV AH,2 ;vai para o visor ler o numero 2 MOV DH,4 MOV DL,1 XOR BH,BH INT 10H CALL ENTDEC ;chama leitura 2 MOV NUM2,AX CALL LESINAL MOV AH,2 ;exibe mensagem do RESULTADO MOV DH,7 MOV DL,15 XOR BH,BH INT 10H MOV AH,9 LEA DX,MSG4 INT 21H MOV AH,2 ;vai para o visor exibir o RESULTADO MOV DH,7 MOV DL,1 XOR BH,BH INT 10H ; CALL CLS ; CALL JANELA ; CALL SAIDEC CALL SAI MAIN ENDP ;========================================================== ;DESENHA JANELA PRINCIPAL ;========================================================== JANELA PROC CALL CLS MOV AH,6 ;shadow da janela MOV AL,0 MOV BH,00000000b MOV CH,01 MOV CL,01 MOV DH,17 MOV DL,57 INT 10H MOV AH,6 ;janela BG branco FG azul MOV AL,0 MOV BH,01001111b MOV CH,00 MOV CL,00 MOV DH,16 MOV DL,56 INT 10H MOV AH,9 ;moldura topo LEA DX,MOLD1 INT 21H MOV CX,15 ;loop da vertical (na lateral) BLOOP: MOV AH,9 LEA DX,MOLD2 INT 21H DEC CX JNZ BLOOP MOV AH,9 ;moldura baixo LEA DX,MOLD3 INT 21H MOV AH,2 ;titulo calculadora MOV DH,1 MOV DL,2 XOR BH,BH INT 10H MOV AH,9 LEA DX,TITULO INT 21H MOV AH,2 ;titulo mensagens MOV DH,2 MOV DL,15 XOR BH,BH INT 10H MOV AH,9 LEA DX,TIT2 INT 21H MOV AH,2 ;titulo erros MOV DH,8 MOV DL,15 XOR BH,BH INT 10H MOV AH,9 LEA DX,TIT3 INT 21H MOV AH,2 ;moldura intermediaria horiz MOV DH,2 MOV DL,1 XOR BH,BH INT 10H MOV AH,9 LEA DX,MOLD4 INT 21H MOV AH,6 ;visor BG azul FG branco MOV AL,0 XOR BH,00001111b MOV CH,03 MOV CL,01 MOV DH,07 MOV DL,13 INT 10H MOV AH,6 ;visor .:MENSAGENS:. BG azul FG branco MOV AL,0 ;XOR BH,00001111b MOV CH,03 MOV CL,15 MOV DH,07 MOV DL,55 INT 10H MOV AH,6 ;visor .:ERROS:. BG azul FG branco MOV AL,0 ;XOR BH,00001111b MOV CH,09 MOV CL,15 MOV DH,09 MOV DL,55 INT 10H RET JANELA ENDP ;========================================================== ;ENTDEC - Le o numero e salva em AX ;========================================================== ENTDEC PROC ;le um numero decimal da faixa de -32768 a +32767 ;variaveis de entrada: nehuma (entrada de digitos pelo teclado) ;variaveis de saida: AX -> valor binario equivalente do numero decimal PUSH BX PUSH CX PUSH DX ;salvando registradores que serão usados XOR BX,BX ;BX acumula o total, valor inicial 0 XOR CX,CX ;CX indicador de sinal (negativo = 1), inicial = 0 ;entrada de número: mensagem adequada já exibida para o usuário anteriormente MOV AH,1h INT 21h ;le caracter no AL CMP AL, '-' ;sinal negativo? JE MENOS CMP AL,'+' ;sinal positivo? JE MAIS JMP NUM ;se nao é sinal, então vá processar o caracter MENOS: MOV CX,1 ;negativo = verdadeiro MAIS: INT 21h ;le um outro caracter NUM: AND AX,000Fh ;junta AH a AL, converte caracter para binário PUSH AX ;salva AX (valor binário) na pilha MOV AX,10 ;prepara constante 10 MUL BX ;AX = 10 x total, total está em BX POP BX ;retira da pilha o valor salvo, vai para BX ADD BX,AX ;total = total x 10 + valor binário MOV AH,1h INT 21h ;le um caracter CMP AL,0Dh ;é o CR ? JNE NUM ;se não, vai processar outro dígito em NUM MOV AX,BX ;se é CR, então coloca o total calculado em AX CMP CX,1 ;o numero é negativo? JNE SAIDA ;não NEG AX ;sim, faz-se seu complemento de 2 SAIDA: POP DX POP CX POP BX ;restaura os conteúdos originais RET ;retorna a rotina que chamou ENTDEC ENDP ;========================================================== ;SAIDEC - exibe o resultado contido em AX ;========================================================== SAIDEC PROC ;exibe o conteudo de AX como decimal inteiro com sinal ;variaveis de entrada: AX -> valor binario equivalente do número decimal ;variaveis de saida: nehuma (exibição de dígitos direto no monitor de video) PUSH AX PUSH BX PUSH CX PUSH DX ;salva na pilha os registradores usados OR AX,AX ;prepara comparação de sinal JGE PT1 ;se AX maior ou igual a 0, vai para PT1 PUSH AX ;como AX menor que 0, salva o número na pilha MOV DL,'-' ;prepara o caracter ' - ' para sair MOV AH,2h ;prepara exibição INT 21h ;exibe ' - ' POP AX ;recupera o número NEG AX ;troca o sinal de AX (AX = - AX) ;obtendo dígitos decimais e salvando-os temporariamente na pilha PT1: XOR CX,CX ;inicializa CX como contador de dígitos MOV BX,10 ;BX possui o divisor PT2: XOR DX,DX ;inicializa o byte alto do dividendo em 0; o restante é AX DIV BX ;após a execução, AX = quociente; DX = resto PUSH DX ;salva o primeiro dígito decimal na pilha (1o. resto) INC CX ;contador = contador + 1 OR AX,AX ;quociente = 0 ? (teste de parada) JNE PT2 ;não, continuamos a repetir o laço ;exibindo os dígitos decimais (restos) no monitor, na ordem inversa MOV AH,2h ;sim, termina o processo, prepara exibição dos restos PT3: POP DX ;recupera dígito da pilha colocando-o em DL (DH = 0) ADD DL,30h ;converte valor binário do dígito para caracter ASCII INT 21h ;exibe caracter LOOP PT3 ;realiza o loop ate que CX = 0 POP DX ;restaura o conteúdo dos registros POP CX POP BX POP AX ;restaura os conteúdos dos registradores RET ;retorna à rotina que chamou SAIDEC ENDP ;========================================================== ;LESINAL ;========================================================== LESINAL PROC MOV AH,2 ;exibe mensagem de leitura do sinal MOV DH,5 MOV DL,15 XOR BH,BH INT 10H MOV AH,9 LEA DX,MSG3 INT 21H MOV AH,2 ;vai para o visor ler o sinal MOV DH,5 MOV DL,1 XOR BH,BH INT 10H MOV AH,1 ;le sinal INT 21H MOV SINAL,AL ; ;comparacao para a soma ; CMP AL,01H ;01H='h' <<< ESC ; JE XESC ; CMP AL,02BH ;02bh='+' ; JE XSOMA ; ;comparacao para a subtracao ; CMP AL,02DH ;02DH= '-' ; JE XSUBT ; ;comparacao para a multiplicacao ; CMP AL,02AH ;02AH='*' ; JE XMULT ; ;comparacao para divisao ; CMP AL,02FH ;02FH='/' ; JE XDIVI ; CMP AL,062H ;062H='b' ; JE XBINA ; CMP AL,068H ;068H='h' ; JE XHEXA ;CASO NAO FOR NENHUMA FUNCAO VALIDA MOSTRA ERRO MOV AH,2 ;vai para o visor exiber msg de erro MOV DH,9 MOV DL,15 XOR BH,BH INT 10H MOV AH,9 ;exime msg de erro de sinal ERRO1 LEA DX,ERRO1 INT 21H ; XSOMA: ; CALL SOMA ; JMP SAIFUNC ; XSUBT: ; CALL SUBT ; JMP SAIFUNC ; XMULT: ; CALL MULT ; JMP SAIFUNC ; XDIVI: ; CALL DIVI ; JMP SAIFUNC ; XBINA: ; CALL BINA ; JMP SAIFUNC ; XHEXA: ; CALL HEXA ; JMP SAIFUNC ; XESC: ; CALL SAI SAIFUNC: RET LESINAL ENDP ;========================================================== ;CLEARSCREEN - limpa tela ;========================================================== CLS PROC MOV AH,6 MOV AL,0 MOV BH,01110000b MOV CH,00 MOV CL,00 MOV DH,24 MOV DL,79 INT 10H RET CLS ENDP ;========================================================== ;ERRO ;========================================================== ;ERRO PROC ; RET ;ERRO ENDP ;========================================================== ;SAI ;========================================================== SAI PROC MOV AH,4CH ;sai para o dos INT 21H RET SAI ENDP END MAIN