Skip to content

Instantly share code, notes, and snippets.

@blabos-zz
Created November 21, 2010 23:23
Show Gist options
  • Save blabos-zz/709270 to your computer and use it in GitHub Desktop.
Save blabos-zz/709270 to your computer and use it in GitHub Desktop.
Calc
; +----+----+----+
; | 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