Created
November 21, 2010 23:23
-
-
Save blabos-zz/709270 to your computer and use it in GitHub Desktop.
Calc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; +----+----+----+ | |
; | 1 | 2 | 3 | row0 | |
; +----+----+----+ | |
; | 4 | 5 | 6 | row1 | |
; +----+----|----+ | |
; | 7 | 8 | 9 | row2 | |
; +----+----+----+ | |
; | A | 0 | B | row3 | |
; +----+----+----+ | |
; col0 col1 col2 | |
; Numeros do display de 7 segmentos | |
mov 0x70, #11000000b ; 0 | |
mov 0x71, #11111001b ; 1 | |
mov 0x72, #10100100b ; 2 | |
mov 0x73, #10110000b ; 3 | |
mov 0x74, #10011001b ; 4 | |
mov 0x75, #10010010b ; 5 | |
mov 0x76, #10000010b ; 6 | |
mov 0x77, #11111000b ; 7 | |
mov 0x78, #10000000b ; 8 | |
mov 0x79, #10010000b ; 9 | |
mov 0x7a, #10111001b ; + | |
mov 0x7b, #10110111b ; = | |
start: | |
call get_user_input | |
call convert_operands | |
call sum_16_bits | |
call convert_output | |
call show_output | |
jmp start | |
jmp end_prog | |
; Faz pooling no teclado | |
; Se uma tecla for pressionada coloca r7 em #0x01 e o valor da tecla | |
; em r6. Enquanto nao houver tecla pressionada mantem em r6 o valor | |
; da ultima tecla pressionada, mas coloca #0x00 em r7 | |
; | |
; Le e escreve nos registradores: | |
; Got Key: r7 | |
; Key Pressed: r6 | |
; Current Row: r5 | |
key_scan: | |
mov r7, #0x00 | |
mov p0, #0xff | |
; Scanning my line 0 (upper -> computer line 3) | |
setb p0.0 | |
clr p0.3 | |
mov r5, #0x00 ; Row number | |
call col_scan | |
cjne r7, #0x00, key_scan_end | |
; Scanning line 1 | |
setb p0.3 | |
clr p0.2 | |
mov r5, #0x01 ; Row number | |
call col_scan | |
cjne r7, #0x00, key_scan_end | |
; Scanning line 2 (upper) | |
setb p0.2 | |
clr p0.1 | |
mov r5, #0x02 ; Row number | |
call col_scan | |
cjne r7, #0x00, key_scan_end | |
; Scanning line 3 | |
setb p0.1 | |
clr p0.0 | |
mov r5, #0x03 ; Row number | |
call col_scan | |
cjne r7, #0x00, key_scan_zero | |
key_scan_zero: | |
cjne r6, #0x0b, key_scan_end | |
mov r6, #0x00 | |
key_scan_end: | |
ret | |
col_scan: | |
mov a, r5 | |
mov b, #0x03 | |
mul ab | |
jnb P0.6, col_0 | |
jnb P0.5, col_1 | |
jnb P0.4, col_2 | |
jmp col_scan_end | |
col_0: | |
add a, #0x01 | |
jnb P0.6, $ | |
jmp col_scan_got_key | |
col_1: | |
add a, #0x02 | |
jnb P0.5, $ | |
jmp col_scan_got_key | |
col_2: | |
add a, #0x03 | |
jnb P0.4, $ | |
jmp col_scan_got_key | |
col_scan_got_key: | |
mov r7, #0x01 | |
mov r6, a | |
col_scan_end: | |
ret | |
; Le do teclado uma string contendo o primeiro operando, seguido | |
; pelo operador ('*' -> #0x0a), seguido pelo segundo operando e | |
; finalmente o sinal '#' (#0x0c) que indica o fim da leitura para | |
; realizacao do calculo. | |
; | |
; Essa string eh armazenada nos enderecos 0x60 a 0x69 | |
; | |
; Le os registradores: | |
; Got Key: r7 | |
; Key Pressed: r6 | |
get_user_input: | |
mov r0, #0x5f | |
mov r4, #0x04 | |
next_key: | |
inc r0 | |
dec r4 | |
read_key: | |
call key_scan | |
cjne r7, #0x01, read_key | |
; apenas para display | |
mov a, r6 | |
mov r3, a | |
call is_digit | |
mov r2, a | |
cjne r2, #0x00, no_reset_display_1 ; Se num, nao reseta | |
mov r4, #0x03 ; Escolhe prim display | |
no_reset_display_1: ; Pra mostrar dig corr | |
cjne r3, #0x0c, no_adjust_equal ; Ajusta valor pra = | |
mov r3, #0x0b ; | |
no_adjust_equal: ; | |
call display ; mostra | |
cjne r2, #0x00, no_reset_display_2 ; Se num, nao reseta | |
mov r4, #0x04 ; Recomeca pro proximo | |
no_reset_display_2: | |
; Segue a logica de leitura | |
mov a, r6 | |
mov @r0, a | |
cjne @r0, #0x0c, next_key | |
ret | |
; Converte a string de entrada em valores. O primeiro valor eh | |
; armazenado nos enderecos 0x6a (H) e 0x6b (L), enquanto que o | |
; segundo valor eh armazenado nos enderecos 0x6c (H) e 0x6d (L). | |
; Basicamente vai somando o valor do caracter e fazendo shift | |
; decimal (X 0x0a) ate encontrar um nao-digito. | |
; Ha uma repeticao de codigo que eu nao tive saco de melhorar | |
convert_operands: | |
mov r0, #0x5f | |
mov 0x6a, #0x00 | |
mov 0x6b, #0x00 | |
first_operand: | |
inc r0 | |
mov a, @r0 | |
call is_digit | |
jz next_operand | |
mul_by_10_1: | |
mov a, 0x6b | |
mov b, #0x0a | |
mul ab | |
mov 0x6b, a | |
mov r1, b | |
cjne r1, #0x00, calc_with_word_1 | |
mov a, 0x6a | |
mov b, #0x0a | |
mul ab | |
mov 0x6a, a | |
jmp read_and_sum_1 | |
calc_with_word_1: | |
mov a, 0x6a | |
mov b, #0x0a | |
mul ab | |
add a, r1 | |
mov 0x6a, a | |
read_and_sum_1: | |
mov a, @r0 | |
add a, 0x6b | |
mov 0x6b, a | |
jnz sum_without_carry_1 | |
inc 0x6a | |
sum_without_carry_1: | |
jmp first_operand | |
next_operand: | |
mov 0x6c, #0x00 | |
mov 0x6d, #0x00 | |
second_operand: | |
inc r0 | |
mov a, @r0 | |
call is_digit | |
jz convert_end | |
mul_by_10: | |
mov a, 0x6d | |
mov b, #0x0a | |
mul ab | |
mov 0x6d, a | |
mov r1, b | |
cjne r1, #0x00, calc_with_word_2 | |
mov a, 0x6c | |
mov b, #0x0a | |
mul ab | |
mov 0x6c, a | |
jmp read_and_sum_2 | |
calc_with_word_2: | |
mov a, 0x6c | |
mov b, #0x0a | |
mul ab | |
add a, r1 | |
mov 0x6c, a | |
read_and_sum_2: | |
mov a, @r0 | |
add a, 0x6d | |
mov 0x6d, a | |
jnz sum_without_carry_2 | |
inc 0x6c | |
sum_without_carry_2: | |
jmp second_operand | |
convert_end: | |
ret | |
; Soma dois numeros de 16 bits. A soma eh a unica operacao | |
; implementada por este programa | |
; Toma como primeiro operando o valore nos enderecos | |
; 0x6a(H) e 0x6b(L), como segundo operando o valor nos enderecos | |
; 0x6c(H) e 0x6d(L), retornando o resultado nos enderecos | |
; 0x6e(H) e 0x6f(L) | |
sum_16_bits: | |
clr cy | |
mov a, 0x6b | |
add a, 0x6d | |
mov 0x6f, a | |
mov a, 0x6a | |
addc a, 0x6c | |
mov 0x6e, a | |
ret | |
; Escreve no acc #0x01 caso o valor inicial de acc esteja na faixa | |
; 0x00 a 0x09, caso contrario escreve 0x00 no acc. | |
is_digit: | |
clr cy | |
subb a, #0x0a | |
jc got_digit | |
jmp not_digit | |
got_digit: | |
mov a, #0x01 | |
jmp is_digit_end | |
not_digit: | |
mov a, #0x00 | |
is_digit_end: | |
ret | |
; Mostra no dysplay X o digito Y. espera receber o numero do display | |
; no registrador r4 e o digito no registrador r3 | |
display: | |
call display_setup | |
mov a, #0x70 | |
add a, r3 | |
mov r1, a | |
mov p1, @r1 | |
ret | |
; seleciona o display indicado no registrador r4 | |
display_setup: | |
mov a, #11100111b ; Mascara para limpar os bits 3 e 4 | |
anl a, p3 ; Limpa os bits 3 e 4. Mantem os outros | |
mov p3, a ; Reconfigura porta com bits 3 e 4 = 0 | |
mov b, r4 ; Le o numero do display 3, 2, 1 ou 0 | |
mov a, #0x01 ; Se o display for 1 ou 3 seta p3.3 | |
anl a, b | |
jz no_set_p33 | |
setb p3.3 | |
no_set_p33: | |
mov a, #0x02 ; Se o display for 2 ou 3 seta p3.4 | |
anl a, b | |
jz display_setup_end | |
setb p3.4 | |
display_setup_end: | |
ret | |
; Dividendo | |
; r7: msb | |
; r6: lsb | |
; | |
; Divisor | |
; r5 | |
; | |
; Quociente | |
; r4: msb | |
; r3: lsb | |
; | |
; resto | |
; r2 | |
div_16bit: | |
mov r4, #0x00 | |
mov r3, #0x00 | |
mov r2, #0x00 | |
calc_begin: | |
clr cy | |
mov a, r6 | |
subb a, r5 | |
mov r6, a | |
jnc no_carry_1 | |
mov a, r7 | |
jz calc_end | |
dec r7 | |
no_carry_1: | |
mov a, r3 | |
add a, #0x01 | |
mov r3, a | |
jnc no_carry_2 | |
mov a, r4 | |
add a, #0x01 | |
mov r4, a | |
no_carry_2: | |
jmp calc_begin | |
calc_end: | |
mov a, r6 | |
add a, r5 | |
mov r2, a | |
ret | |
convert_output: | |
mov r7, 0x6e | |
mov r6, 0x6f | |
mov r5, #0x0a | |
call div_16bit | |
mov 0x6e, r4 | |
mov 0x6f, r3 | |
mov 0x7f, r2 | |
mov r7, 0x6e | |
mov r6, 0x6f | |
mov r5, #0x0a | |
call div_16bit | |
mov 0x6e, r4 | |
mov 0x6f, r3 | |
mov 0x7e, r2 | |
mov r7, 0x6e | |
mov r6, 0x6f | |
mov r5, #0x0a | |
call div_16bit | |
mov 0x6e, r4 | |
mov 0x6f, r3 | |
mov 0x7d, r2 | |
mov r7, 0x6e | |
mov r6, 0x6f | |
mov r5, #0x0a | |
call div_16bit | |
mov 0x6e, r4 | |
mov 0x6f, r3 | |
mov 0x7c, r2 | |
ret | |
; Mostra resultado | |
show_output: | |
mov r4, #0x03 | |
mov r3, 0x7c | |
call display | |
mov r4, #0x02 | |
mov r3, 0x7d | |
call display | |
mov r4, #0x01 | |
mov r3, 0x7e | |
call display | |
mov r4, #0x00 | |
mov r3, 0x7f | |
call display | |
ret | |
end_prog: | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment