;-----------------------------------------------------------------------------
; J.Rubio. Código ensamblador 8085 para fuente de alimentación.
; www.tecnofilos.org
;-----------------------------------------------------------------------------
                lxi     sp,Cima_Pila
                call    IniciaPia
                call    IniciaVariables
                call    IniciaPantalla
                call    DigitalizaTension
                call    DigitalizaCorriente
                mvi     a,40
                sta     Delay0
;-----------------------------------------------------------------------------
; Rutina principal del programa.
;-----------------------------------------------------------------------------
inicio:
                call    RefrescaDisplay
barrido00:                                  ;bucle de barrido de displays
                lda     Delay0
                dcr     a
                sta     Delay0
                jnz     noiguales
                call    DigitalizaTension
                call    DigitalizaCorriente
                mvi     a,40
                sta     Delay0
noiguales:
                in      Pc                   ;Lee el teclado
                ani     00001111b
                cpi     TeclaOk
                jz      Potencia
                jmp     inicio
;-----------------------------------------------------------------------------
; Fin de la rutina principal del programa.
;-----------------------------------------------------------------------------
Potencia:
                mvi     a,40
                sta     Delay0
                call    MultiplicaVxI
CP00:
                call    RefrescaDisplay
                lda     Delay0
                dcr     a
                sta     Delay0
                jnz      CP01
                call    DigitalizaTension
                call    DigitalizaCorriente
                call    MultiplicaVxI
                mvi     a,40
                sta     Delay0
CP01:
                in      Pc
                ani     00001111b
                cpi     TeclaEsc
                jz      inicio
                jmp     CP00
;-----------------------------------------------------------------------------
MultiplicaVxI:
                push    psw
                push    h
                push    b
                lda     TENSION
                sta     A0
                mvi     a,0
                sta     A1
                sta     A2
                sta     A3
                mvi     a,20
                sta     B0
                mvi     a,0
                sta     B1
                sta     B2
                sta     B3
                call    MultiplicaAxB ;Tenemos en R la tension en binario
                lda     R0
                sta     C0
                lda     R1
                sta     C1
                lda     R2
                sta     C2
                lda     R3
                sta     C3   ; y la guardamos en C

                lda     CORRIENTE
                sta     A0
                mvi     a,0
                sta     A1
                sta     A2
                sta     A3
                mvi     a,5
                sta     B0
                mvi     a,0
                sta     B1
                sta     B2
                sta     B3
                call    MultiplicaAxB ;Tenemos en R la corriente en binario

                lda     R0
                sta     B0
                lda     R1
                sta     B1
                lda     R2
                sta     B2
                lda     R3
                sta     B3  ; en B tenemos la corriente

                lda     C0
                sta     A0
                lda     C1
                sta     A1
                lda     C2
                sta     A2
                lda     C3
                sta     A3   ; en A tenemos la tension
                call    MultiplicaAxB
                call    BinToDec
                lda     C1
                mov     c,a
                lda     C2
                mov     b,a
                call    MuestraCorrienteBcd
                mvi     a,2
                call    PuntoOn
                lxi     h,Pot.
                call    EscribeIzq
                lda     d3
                cpi     192
                jnz     MVI00
                mvi     a,255
                sta     d3
MVI00:
                pop     b
                pop     h
                pop     psw
                ret
;-----------------------------------------------------------------------------
; R = A * B ; Multiplica en binario. Argumentos en 16 bit y resultado en 32.
;-----------------------------------------------------------------------------
MultiplicaAxB:
                push    psw
                push    d
                mvi     a,0
                sta     R0
                sta     R1
                sta     R2
                sta     R3   ;pone a cero el resultado
                mvi     e,16      ;se van a desplazar 16 bits
VI00:
                lda     B0
                ani     00000001b   ;Tenemos el bit0
                cpi     1
                jz      bit1
                jmp     bit0
bit1:
                call    RigualRmasA
bit0:
                call    Rota_A_Izq
                call    Rota_B_Der
                dcr     e
                jnz     VI00
                pop     d
                pop     psw
                ret
;-----------------------------------------------------------------------------
; Suma en binario
;-----------------------------------------------------------------------------
RigualRmasA:
                push    psw
                push    b
                lda     A0
                mov     b,a    ;b = A0
                lda     R0
                add     b     ; a = a + b  <=> R0 = R0 + A0
                sta     R0               
                lda     A1
                mov     b,a
                lda     R1
                adc     b
                sta     R1   ; R1 = R1 + A1 + Carry
                lda     A2
                mov     b,a
                lda     R2
                adc     b
                sta     R2   ; R2 = R2 + A2 + Carry
                lda     A3
                mov     b,a
                lda     R3
                adc     b
                sta     R3   ; R3 = R3 + A3 + Carry
                pop     b
                pop     psw
                ret
;-----------------------------------------------------------------------------
; Suma en BCd
;-----------------------------------------------------------------------------
CigualCmasA:
                push    psw
                push    b
                lda     A0
                mov     b,a    ;b = A0
                lda     C0
                add     b     ; a = a + b  ;
                daa
                sta     C0
                lda     A1
                mov     b,a
                lda     C1
                adc     b
                daa
                sta     C1
                lda     A2
                mov     b,a
                lda     C2
                adc     b
                daa
                sta     C2
                lda     A3
                mov     b,a
                lda     C3
                adc     b
                daa
                sta     C3
                pop     b
                pop     psw
                ret
;-----------------------------------------------------------------------------
; Convierte: C(BCD) = R(Binario) en 32 bit Destruye R
;-----------------------------------------------------------------------------
BinToDec:
                push    psw
                push    h
                push    b
                push    d
                mvi     a,0
                sta     C0
                sta     C1
                sta     C2
                sta     C3     ;C = 0 
                mvi     e,23    
                lxi     h,ConvDec00
BTD00:
                mov     a,m
                sta     A0
                inx     h
                mov     a,m
                sta     A1
                inx     h
                mov     a,m
                sta     A2
                inx     h
                mov     a,m
                sta     A3
                inx     h
                lda     R0     ;Obtiene el bit LSB
                ani     00000001b
                cpi     1
                jz      BTDbit1
                jmp     BTDbit0
BTDbit1:
                call    CigualCmasA
BTDbit0:
                call    Rota_R_Der
                dcr     e
                jnz     BTD00
                pop     d
                pop     b
                pop     h
                pop     psw
                ret
;-----------------------------------------------------------------------------
Rota_A_Izq:
                push    psw
                stc
                cmc    ;CY = 0
                lda     A0
                ral
                sta     A0
                lda     A1
                ral
                sta     A1
                lda     A2
                ral
                sta     A2
                lda     A3
                ral
                sta     A3
                pop     psw
                ret
;-----------------------------------------------------------------------------
Rota_R_Der:
                push    psw
                stc
                cmc     ;CY = 0
                lda     R3
                rar
                sta     R3
                lda     R2
                rar
                sta     R2
                lda     R1
                rar
                sta     R1
                lda     R0
                rar
                sta     R0   ;CY contiene el valor de BD0
                pop     psw
                ret
;-----------------------------------------------------------------------------
Rota_C_Der:
                push    psw
                stc
                cmc     ;CY = 0
                lda     C3
                rar
                sta     C3
                lda     C2
                rar
                sta     C2
                lda     C1
                rar
                sta     C1
                lda     C0
                rar
                sta     C0   ;CY contiene el valor de BD0
                pop     psw
                ret
;-----------------------------------------------------------------------------
Rota_B_Der:
                push    psw
                stc
                cmc     ;CY = 0
                lda     B3
                rar
                sta     B3
                lda     B2
                rar
                sta     B2
                lda     B1
                rar
                sta     B1
                lda     B0
                rar
                sta     B0   ;CY contiene el valor de BD0
                pop     psw
                ret
;-----------------------------------------------------------------------------
IniciaVariables:
                push    psw
                mvi     a,40
                sta     FinDelay0
                mvi     a,0
                sta     FinDelay1  ;Retardo de muestreo 
                sta     Delay0     ;Reset al contador de retardo
                sta     Delay1
                pop     psw
                ret
;-----------------------------------------------------------------------------
ResetDelay:
                push    psw
                mvi     a,0
                sta     Delay0
                pop     psw
                ret
;-----------------------------------------------------------------------------
DecrementaDelay:
                push    psw
                lda     Delay0
                dcr     a
                pop     psw
                ret
;-----------------------------------------------------------------------------
;Devuelve a=1 si son iguales sino devuelve a=0
FinDelay:
                push    b

                lda     Delay0
                mov     b,a       ; b = Delay0
                lda     FinDelay0 ; a = FinDelay0
                cmp     b   ;b=a?
                jnz     FD00      ;no son iguales se sale

                lda     Delay1
                mov     b,a
                lda     FinDelay1
                cmp     b
                jnz     FD00

                mvi     a,1   ;Llega aqu¡ si son los dos iguales.
                pop     b
                ret          
FD00:
                mvi     a,0 ; no son iguales
                pop     b
                ret
;-----------------------------------------------------------------------------
DigitalizaTension:
                push    psw
                push    b
                push    d
                push    h
                in      Pb
                ani     00011111b
                out     Pb      ;Seleccionamos la entrada 0 del multiplexor.
                call    Retardo100us
                call    Retardo100us
                out     AD              ;Comienza la digitalizacion
                call    Retardo100us
                call    Retardo100us
                in      AD
                sta     TENSION          ;Tenemos el valor en rango 00h-FFh

                               ; bc = 0,TENSION
                ral            ; a = a * 2;
                mov     c,a    ; c = a * 2;
                mvi     a,0
                ral
                mov     b,a ;tenemos en BC = TENSION * 2
                            
                lxi     h,Tensiones000
                dad     b   ; hl = hl + bc
                mov     b,m   ;b=parte alta
                inx     h
                mov     c,m

                ;lda     TENSION
                ;sta     A0
                ;mvi     a,0
                ;sta     A1
                ;sta     A2
                ;sta     A3

                ;mvi     a,20
                ;sta     B0
                ;mvi     a,0
                ;sta     B1
                ;sta     B2
                ;sta     B3
                ;call    MultiplicaAxB
                ;call    BinToDec

                ;lda     C0
                ;mov     c,a
                ;lda     C1
                ;mov     b,a

                call    MuestraTensionBcd
                mov     a,c
                lda     TensionBcd0
                mov     a,b
                lda     TensionBcd1
                mvi     a,6      ;Coloca el punto decimal
                call    PuntoOn
                mvi     a,V      ;Coloca el s¡mbolo de Voltios.
                sta     d4
                lda     d7      ;Quita el primer cero si lo hay.
                cpi     192
                jnz     DT01
                mvi     a,255
                sta     d7
DT01:
                pop     h
                pop     d
                pop     b
                pop     psw
                ret
;-----------------------------------------------------------------------------
DigitalizaCorriente:
                push    psw
                push    b
                push    d
                push    h
                in      Pb
                ani     00011111b
                ori     00100000b
                out     Pb
                call    Retardo100us
                call    Retardo100us
                out     AD              ;Comienza la digitalizacion
                call    Retardo100us
                call    Retardo100us
                in      AD
                sta     CORRIENTE          ;Tenemos el valor en rango 00h-FFh

                               ; bc = 0,CORRIENTE
                ral            ; a = a * 2;
                mov     c,a    ; c = a * 2;
                mvi     a,0
                ral
                mov     b,a ;tenemos en BC = CORRIENTE * 2
                             
                lxi     h,Corrientes000
                dad     b   ; hl = hl + bc
                mov     b,m   ;b=parte alta
                inx     h
                mov     c,m

                ;lda     CORRIENTE
                ;sta     A0
                ;mvi     a,0
                ;sta     A1
                ;sta     A2
                ;sta     A3

                ;mvi     a,5
                ;sta     B0
                ;mvi     a,0
                ;sta     B1
                ;sta     B2
                ;sta     B3
                ;call    MultiplicaAxB
                ;call    BinToDec
                ;lda     C0
                ;mov     c,a
                ;lda     C1
                ;mov     b,a
                call    MuestraCorrienteBcd
                mov     a,c
                lda     CorrienteBcd0
                mov     a,b
                lda     CorrienteBcd1
                mvi     a,2      ;Coloca el punto decimal
                call    PuntoOn
                lda     d3
                cpi     192
                jnz     DC00
                mvi     a,255
                sta     d3
DC00:
                pop     h
                pop     d
                pop     b
                pop     psw
                ret
;-----------------------------------------------------------------------------
RefrescaDisplay:
                push    psw
                push    h
                push    b
                call    IniciaPantalla
                lxi     h,d7
                mvi     b,8
barrido01:
                mov     a,m
                out     Pa
                call    Retardo1ms ;2 ms por d¡gito 
                ;call    Retardo1ms ;16ms -> 62.5 Hz f. de refresco.
                mvi     a,255
                out     Pa
                ;FlancoBajada
                in      Pb
                ori     00000001b
                out     Pb
                ani     11111110b
                out     Pb
                dcr     l
                dcr     b
                jnz     barrido01 ;Hasta aqui ha hecho un barrido de 8 d¡gitos
                pop     b
                pop     h
                pop     psw
                ret
;-----------------------------------------------------------------------------
EscribeIzq:
                push    psw
                push    h
                mov     a,m
                sta     d7
                inr     l
                mov     a,m
                sta     d6
                inr     l
                mov     a,m
                sta     d5
                inr     l
                mov     a,m
                sta     d4
                inr     l
                pop     h
                pop     psw
                ret
;------------------------------------------------------------------------------
EscribeDer:
                push    psw
                push    h
                mov     a,m
                sta     d3
                inr     l
                mov     a,m
                sta     d2
                inr     l
                mov     a,m
                sta     d1
                inr     l
                mov     a,m
                sta     d0
                inr     l
                pop     h
                pop     psw
                ret
;----------------------------------------------------------------------------
;En a entra el punto que se quiere encender.
PuntoOn:
                push    psw
                push    h
                lxi     h,d0
                add     l
                mov     l,a
                mov     a,m
                ani     01111111b
                mov     m,a
                pop     h
                pop     psw
                ret
;-----------------------------------------------------------------------------
;Le entran b y c que est n en bcd
MuestraTensionBcd:
                push    psw
                push    h
                push    b
                mov     a,c
                ani     00001111b ;nibble bajo
                lxi     h,Numeros
                add     l         ; a = a + l
                mov     l,a
                mov     a,m
                sta     d4
                mov     a,c
                ani     11110000b ; nibble alto
                rrc
                rrc
                rrc
                rrc
                lxi     h,Numeros
                add     l
                mov     l,a
                mov     a,m
                sta     d5
                mov     a,b
                ani     00001111b ;nibble bajo
                lxi     h,Numeros
                add     l         ; a = a + l
                mov     l,a
                mov     a,m
                sta     d6
                mov     a,b
                ani     11110000b ; nibble alto
                rrc
                rrc
                rrc
                rrc
                lxi     h,Numeros
                add     l
                mov     l,a
                mov     a,m
                sta     d7
                pop     b
                pop     h
                pop     psw
                ret
;--------------------------------------------------------------------------------
MuestraCorrienteBcd:
                push    psw
                push    h
                push    b
                mov     a,c
                ani     00001111b ;nibble bajo
                lxi     h,Numeros
                add     l         ; a = a + l
                mov     l,a
                mov     a,m
                sta     d0 ;4
                mov     a,c
                ani     11110000b ; nibble alto
                rrc
                rrc
                rrc
                rrc
                lxi     h,Numeros
                add     l
                mov     l,a
                mov     a,m
                sta     d1 ;5
                mov     a,b
                ani     00001111b ;nibble bajo
                lxi     h,Numeros
                add     l         ; a = a + l
                mov     l,a
                mov     a,m
                sta     d2  ;6
                mov     a,b
                ani     11110000b ; nibble alto
                rrc
                rrc
                rrc
                rrc
                lxi     h,Numeros
                add     l
                mov     l,a
                mov     a,m
                sta     d3 ;7
                pop     b
                pop     h
                pop     psw
                ret
;-----------------------------------------------------------------------------
IniciaPantalla:
                push    psw
                mvi     a,255
                out     Pa
                in      Pb
                ori     00000010b  ;se pone a 1 Rst
                out     Pb
                in      Pb
                ani     11111101b
                out     Pb
                pop     psw
                ret
;----------------------------------------------------------------------------
Cls:
                push    psw
                mvi     a,255
                sta     d7
                sta     d6
                sta     d5
                sta     d4
                sta     d3
                sta     d2
                sta     d1
                sta     d0
                pop     psw
                ret
;-----------------------------------------------------------------------------
IniciaPia:
                push    psw
                mvi     a,00000011b ;Pa y Pb salida Pc entrada.
                out     Control
                mvi     a,0
                out     Pb
                pop psw
                ret
;-----------------------------------------------------------------------------
FlancoBajada:
                push    psw
                in      Pb
                ori     00000001b
                out     Pb
                ani     11111110b
                out     Pb
                pop     psw
                ret
;-----------------------------------------------------------------------------
CeroCk:
                push    psw
                in      Pb
                ani     11111110b
                out     Pb
                pop     psw
                ret
;-----------------------------------------------------------------------------
UnoCk:
                push    psw
                in      Pb
                ori     00000001b
                out     Pb        ;pone a uno ck
                pop     psw
                ret
;-----------------------------------------------------------------------------
Retardo100us:
                push b
                mvi b,16
lazo100us:
                dcr b
                jnz lazo100us
                pop b
                ret
;-----------------------------------------------------------------------------
Retardo500us:
                push b
                mvi b,105
lazo500us:
                dcr b
                jnz lazo500us
                pop b
                ret
;-----------------------------------------------------------------------------
Retardo1ms:
                push b
                mvi b,218
lazo1ms:
                dcr b
                jnz lazo1ms
                pop b
                ret
;-----------------------------------------------------------------------------
Retardo5ms:
                call    Retardo1ms
                call    Retardo1ms
                call    Retardo1ms
                call    Retardo1ms
                call    Retardo1ms
                ret
;-----------------------------------------------------------------------------
Retardo10ms:
                call    Retardo5ms
                call    Retardo5ms
                ret
;-----------------------------------------------------------------------------
Retardo20ms:
                call    Retardo10ms
                call    Retardo10ms
                ret
;-----------------------------------------------------------------------------
Retardo100ms:
                call    Retardo20ms
                call    Retardo20ms
                call    Retardo20ms
                call    Retardo20ms
                call    Retardo20ms
                ret
;-----------------------------------------------------------------------------
Retardo200ms:
                call    Retardo100ms
                call    Retardo100ms
                ret
;-----------------------------------------------------------------------------
Retardo500ms:
                call    Retardo200ms
                call    Retardo200ms
                call    Retardo100ms
                ret
;-----------------------------------------------------------------------------
Retardo1s:
                call    Retardo200ms
                call    Retardo200ms
                call    Retardo200ms
                call    Retardo200ms
                call    Retardo200ms
                ret
;-----------------------------------------------------------------------------
TesteaLeds:
                push    psw
                mvi     a,0
                sta     FinDelay1
                mvi     a,40
                sta     FinDelay0
                mvi     a,0
                sta     d0
                sta     d1
                sta     d2
                sta     d3
                sta     d4
                sta     d5
                sta     d6
                sta     d7
                call    ResetDelay
TL00:
                call    RefrescaDisplay
                jnz     TL00
                call    ResetDelay
                mvi     a,50
                sta     Delay0
                mvi     a,0
                sta     Delay1
                pop     psw
                ret
;-----------------------------------------------------------------------------
Muestra_R:
                push    psw
                push    b
                lda     R0
                mov     c,a
                lda     R1
                mov     b,a
                call    MuestraCorrienteBcd
                lda     R2
                mov     c,a
                lda     R3
                mov     b,a
                call    MuestraTensionBcd
                pop     b
                pop     psw
                ret
;-----------------------------------------------------------------------------
Muestra_C:
                push    psw
                push    b
                lda     C0
                mov     c,a
                lda     C1
                mov     b,a
                call    MuestraCorrienteBcd
                lda     C2
                mov     c,a
                lda     C3
                mov     b,a
                call    MuestraTensionBcd
                pop     b
                pop     psw
                ret
;-----------------------------------------------------------------------------
Muestra_B:
                push    psw
                push    b
                lda     B0
                mov     c,a
                lda     B1
                mov     b,a
                call    MuestraCorrienteBcd
                lda     B2
                mov     c,a
                lda     B3
                mov     b,a
                call    MuestraTensionBcd
                pop     b
                pop     psw
                ret
;-----------------------------------------------------------------------------
Muestra_A:
                push    psw
                push    b
                lda     A0
                mov     c,a
                lda     A1
                mov     b,a
                call    MuestraCorrienteBcd
                lda     A2
                mov     c,a
                lda     A3
                mov     b,a
                call    MuestraTensionBcd
                pop     b
                pop     psw
                ret
;-----------------------------------------------------------------------------
; Variables y constantes del programa.
;-----------------------------------------------------------------------------
Numeros         .db     192,249,164,176,153,146,130,248,128,144
Pot.            .db     8Ch,0A3h,7,255
.include T.h
.include A.h
ConvDec00       .db     01h,00h,00h,00h
ConvDec01       .db     02h,00h,00h,00h
ConvDec02       .db     04h,00h,00h,00h
ConvDec03       .db     08h,00h,00h,00h
ConvDec04       .db     16h,00h,00h,00h
ConvDec05       .db     32h,00h,00h,00h
ConvDec06       .db     64h,00h,00h,00h
ConvDec07       .db     28h,01h,00h,00h
ConvDec08       .db     56h,02h,00h,00h
ConvDec09       .db     12h,05h,00h,00h
ConvDec10       .db     24h,10h,00h,00h
ConvDec11       .db     48h,20h,00h,00h
ConvDec12       .db     96h,40h,00h,00h
ConvDec13       .db     92h,81h,00h,00h
ConvDec14       .db     84h,63h,01h,00h
ConvDec15       .db     68h,27h,03h,00h
ConvDec16       .db     36h,55h,06h,00h
ConvDec17       .db     72h,10h,13h,00h
ConvDec18       .db     44h,21h,26h,00h
ConvDec19       .db     88h,42h,52h,00h
ConvDec20       .db     76h,85h,04h,01h
ConvDec21       .db     52h,71h,09h,02h
ConvDec22       .db     04h,43h,19h,04h
ConvDec23       .db     08h,86h,38h,08h
TeclaEsc        .equ    00001110b
TeclaOk         .equ    00001101b
TeclaMas        .equ    00001011b
TeclaMenos      .equ    00000111b        
Cima_Pila       .equ    33020
d0              .equ    32768
d1              .equ    32769
d2              .equ    32770
d3              .equ    32771
d4              .equ    32772
d5              .equ    32773
d6              .equ    32774
d7              .equ    32775
IMax0           .equ    32776
IMax1           .equ    32777
CORRIENTE       .equ    32778
TENSION         .equ    32779
TensionBcd0     .equ    32780
TensionBcd1     .equ    32781
CorrienteBcd0   .equ    32782
CorrienteBcd1   .equ    32783
Delay0          .equ    32784
Delay1          .equ    32785
FinDelay0       .equ    32786
FinDelay1       .equ    32787
A0              .equ    32788
A1              .equ    32789
A2              .equ    32790
A3              .equ    32791
B0              .equ    32792
B1              .equ    32793
B2              .equ    32794
B3              .equ    32795
C0              .equ    32796
C1              .equ    32797
C2              .equ    32798
C3              .equ    32799
R0              .equ    32800
R1              .equ    32801
R2              .equ    32802
R3              .equ    32803
TensionBin0     .equ    32804
TensionBin1     .equ    32805
CorrienteBin0   .equ    32806
CorrienteBin1   .equ    32807
Control         .equ    0
Pa              .equ    1
Pb              .equ    2
Pc              .equ    3
AD              .equ    80h
v               .equ    227
V               .equ    193
A               .equ    136

; Pb0 Reloj del contador de display
; Pb1 Reset del contador de display
; Pb5 A ;Del multiplexor anal¢gico.
; Pb6 B
; Pb7 C

.end




