-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProyecto.asm
More file actions
1973 lines (1803 loc) · 65.8 KB
/
Proyecto.asm
File metadata and controls
1973 lines (1803 loc) · 65.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
LOCALS @@
title "EyPC 2023-II Grupo 2 Proyecto - Base"
.model small
.386
.stack 64
;Macros
;clear - Limpia pantalla
clear macro
mov ax,0003h ;ah = 00h, selecciona modo video
;al = 03h. Modo texto, 16 colores
int 10h ;llama interrupcion 10h con opcion 00h.
;Establece modo de video limpiando pantalla
endm
;posiciona_cursor - Cambia la posición del cursor a la especificada con 'renglon' y 'columna'
posiciona_cursor macro renglon,columna
mov dh,renglon ;dh = renglon
mov dl,columna ;dl = columna
mov bx,0
mov ax,0200h ;preparar ax para interrupcion, opcion 02h
int 10h ;interrupcion 10h y opcion 02h. Cambia posicion del cursor
endm
;inicializa_ds - Inicializa el valor del registro DS
inicializa_ds macro
mov ax,@data
mov ds,ax
endm
;muestra_cursor_mouse - Establece la visibilidad del cursor del mouser
muestra_cursor_mouse macro
mov ax,1 ;opcion 0001h
int 33h ;int 33h para manejo del mouse. Opcion AX=0001h
;Habilita la visibilidad del cursor del mouse en el programa
endm
;oculta_cursor_teclado - Oculta la visibilidad del cursor del teclado
oculta_cursor_teclado macro
mov ah,01h ;Opcion 01h
mov cx,2607h ;Parametro necesario para ocultar cursor
int 10h ;int 10, opcion 01h. Cambia la visibilidad del cursor del teclado
endm
;apaga_cursor_parpadeo - Deshabilita el parpadeo del cursor cuando se imprimen caracteres con fondo de color
;Habilita 16 colores de fondo
apaga_cursor_parpadeo macro
mov ax,1003h ;Opcion 1003h
xor bl,bl ;BL = 0, parámetro para int 10h opción 1003h
int 10h ;int 10, opcion 01h. Cambia la visibilidad del cursor del teclado
endm
;imprime_caracter_color - Imprime un caracter de cierto color en pantalla especificado por 'caracter' y 'color'. Los colores disponibles están en la lista a continuacion;
; Colores:
; 00h: Negro
; 01h: Azul
; 02h: Verde
; 03h: Cyan
; 04h: Rojo
; 05h: Magenta
; 06h: Cafe
; 07h: Gris Claro
; 08h: Gris Oscuro
; 09h: Azul Claro
; 0Ah: Verde Claro
; 0Bh: Cyan Claro
; 0Ch: Rojo Claro
; 0Dh: Magenta Claro
; 0Eh: Amarillo
; 0Fh: Blanco
; utiliza int 10h opcion 09h
imprime_caracter_color macro caracter,bg_color,color
mov ah,09h ;preparar AH para interrupcion, opcion 09h
mov al,caracter ;DL = caracter a imprimir
mov bh,0 ;BH = numero de pagina
mov bl,bg_color ;BL (4 bits mas significativos) = color de fondo del caracter
xor bl,color ;BL (4 bits menos significativos) = color del caracter
mov cx,1 ;CX = numero de veces que se imprime el caracter
;CX es un argumento necesario para opcion 09h de int 10h
int 10h ;int 10h, AH=09h, imprime el caracter en AL con el color BL
endm
;lee_mouse - Revisa el estado del mouse
;Devuelve:
;;BX - estado de los botones
;;;Si BX = 0000h, ningun boton presionado
;;;Si BX = 0001h, boton izquierdo presionado
;;;Si BX = 0002h, boton derecho presionado
;;;Si BX = 0003h, boton izquierdo y derecho presionados
; (400,120) => 80x25 =>Columna: 400 x 80 / 640 = 50; Renglon: (120 x 25 / 200) = 15 => 50,15
;;CX - columna en la que se encuentra el mouse en resolucion 640x200 (columnas x renglones)
;;DX - renglon en el que se encuentra el mouse en resolucion 640x200 (columnas x renglones)
lee_mouse macro
mov ax,0003h
int 33h
endm
;comprueba_mouse - Revisa si el driver del mouse existe
comprueba_mouse macro
mov ax,0 ;opcion 0
int 33h ;llama interrupcion 33h para manejo del mouse, devuelve un valor en AX
;Si AX = 0000h, no existe el driver. Si AX = FFFFh, existe driver
endm
.data
;Constantes de colores de modo de video
cNegro equ 00h
cAzul equ 01h
cVerde equ 02h
cCyan equ 03h
cRojo equ 04h
cMagenta equ 05h
cCafe equ 06h
cGrisClaro equ 07h
cGrisOscuro equ 08h
cAzulClaro equ 09h
cVerdeClaro equ 0Ah
cCyanClaro equ 0Bh
cRojoClaro equ 0Ch
cMagentaClaro equ 0Dh
cAmarillo equ 0Eh
cBlanco equ 0Fh
;Valores de color para fondo de carácter
bgNegro equ 00h
bgAzul equ 10h
bgVerde equ 20h
bgCyan equ 30h
bgRojo equ 40h
bgMagenta equ 50h
bgCafe equ 60h
bgGrisClaro equ 70h
bgGrisOscuro equ 80h
bgAzulClaro equ 90h
bgVerdeClaro equ 0A0h
bgCyanClaro equ 0B0h
bgRojoClaro equ 0C0h
bgMagentaClaro equ 0D0h
bgAmarillo equ 0E0h
bgBlanco equ 0F0h
digitos equ 4
baseDec equ 0
baseHex equ 1
baseBin equ 2
resultado dw 0,0 ;resultado es un arreglo de 2 datos tipo word
;el primer dato [resultado] puede guardar el contenido del resultado para la suma, resta, cociente de division o residuo de division
;el segundo dato [resultado+2], en conjunto con [resultado] pueden almacenar la multiplicacion de dos numeros de 16 bits
bf_result db digitos*2 dup(0) ; Buffer para los dígitos del resultado
num1 db digitos dup(0) ; primer numero, en cada localidad guarda 1 digito, puede ser hasta 4 digitos
num2 db digitos dup(0) ; segundo numero, en cada localidad guarda 1 digito, puede ser hasta 4 digitos
num1h dw 0 ; Valor numérico de los caracteres de num1
num2h dw 0 ; Valor numérico de los caracteres de num2
conta1 dw 0
conta2 dw 0
operador db 0 ; Variable para almacenar el operador utilizado en la operación
num_boton db 0
num_impr db 0 ; Variable temporal para imprimir el carácter
baseSel db 0 ; Variable para guardar la base seleccionada
;Auxiliares para calculo de digitos de un numero decimal de hasta 5 digitos
diezmil dw 10000d
mil dw 1000d
cien dw 100d
diez dw 10d
dhex dw 16d
dbin dw 2d
;Auxiliar para calculo de coordenadas del mouse
ocho db 8
;Cuando el driver del mouse no esta disponible
no_mouse db 'No se encuentra driver de mouse. Presione [enter] para salir$'
error_zero db 0ADh,"Divisi",0A2h,"n entre cero! [Enter para continuar]$"
ez_len equ $ - error_zero
;MARCO PRINCIPAL DE LA INTERFAZ GRAFICA
;Caracteres del marco superior
;columnas 000, 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079
marco_sup db 201, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 'C', 'A', 'L', 'C', 'U', 'L', 'A', 'D', 'O', 'R', 'A', 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, '[', 'X', ']', 187
;Caracter del marco lateral
marco_lat db 186
;Caracteres del marco inferior
marco_inf db 200, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 188
;MARCO DE LA CALCULADORA
;Caracteres del marco superior
; 000, 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049
marco_sup_cal db 201, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 187
;Caracter del marco lateral
marco_lat_cal db 186
;Caracter del marco de cruce superior
marco_csup_cal db 203
;Caracter del marco de cruce inferior
marco_cinf_cal db 202
;Caracter del marco de cruce izquierdo
marco_cizq_cal db 204
;Caracter del marco de cruce derecho
marco_cder_cal db 185
;Caracteres del marco inferior
marco_inf_cal db 200, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 188
;Caracter del marco horizontal interno
marco_hint_cal db 205
;Caracter del marco vertical interno
marco_vint_cal db 186
;MARCO DE BOTON
;Caracteres del marco superior
; 000, 001 002 003 004
marco_sup_bot db 218, 196, 196, 196, 191
;Caracter del marco lateral
marco_lat_bot db 179
;Caracteres del marco inferior
marco_inf_bot db 192, 196, 196, 196, 217
;Variables que sirven de parametros para el procedimiento IMPRIME_BOTON
boton_caracter db 0
boton_renglon db 0
boton_columna db 0
boton_color db 0
boton_caracter_color db 0
;Variables tipo byte auxiliares cuando se manejan renglones y columnas dentro de la pantalla
ren_aux db 0
col_aux db 0
.code
inicio:
inicializa_ds
comprueba_mouse ;macro para revisar driver de mouse
xor ax,0FFFFh ;compara el valor de AX con FFFFh, si el resultado es zero, entonces existe el driver de mouse
jz imprime_ui ;Si existe el driver del mouse, entonces salta a 'imprime_ui'
;Si no existe el driver del mouse entonces se ejecutan las siguientes instrucciones
lea dx,[no_mouse]
mov ax,0900h ;opcion 9 para interrupcion 21h
int 21h ;interrupcion 21h. Imprime cadena.
jmp teclado ;salta a 'teclado'
imprime_ui:
clear ;limpia pantalla
oculta_cursor_teclado ;oculta cursor del mouse
apaga_cursor_parpadeo ;Deshabilita parpadeo del cursor
call MARCO_UI ;procedimiento que dibuja marco de la interfaz
call CALCULADORA_UI ;procedimiento que dibuja la calculadora dentro de la interfaz
muestra_cursor_mouse ;hace visible el cursor del mouse
;Revisar que el boton izquierdo del mouse no este presionado
;Si el boton no esta suelto no continua
mouse_no_clic:
lee_mouse
test bx,0001h
jnz mouse_no_clic
;Lee el mouse y avanza hasta que se haga clic en el boton izquierdo
mouse:
lee_mouse
test bx,0001h ;Para revisar si el boton izquierdo del mouse fue presionado
jz mouse ;Si el boton izquierdo no fue presionado, vuelve a leer el estado del mouse
;Leer la posicion del mouse y hacer la conversion a resolucion
;80x25 (columnas x renglones) en modo texto
mov ax,dx ;Copia DX en AX. DX es un valor entre 0 y 199 (renglon)
div [ocho] ;Division de 8 bits
;divide el valor del renglon en resolucion 640x200 en donde se encuentra el mouse
;para obtener el valor correspondiente en resolucion 80x25
xor ah,ah ;Descartar el residuo de la division anterior
mov dx,ax ;Copia AX en DX. AX es un valor entre 0 y 24 (renglon)
mov ax,cx ;Copia CX en AX. CX es un valor entre 0 y 639 (columna)
div [ocho] ;Division de 8 bits
;divide el valor de la columna en resolucion 640x200 en donde se encuentra el mouse
;para obtener el valor correspondiente en resolucion 80x25
xor ah,ah ;Descartar el residuo de la division anterior
mov cx,ax ;Copia AX en CX. AX es un valor entre 0 y 79 (columna)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Aqui va la lógica de la posicion del mouse;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Si el mouse fue presionado en el renglon 0
;se va a revisar si fue dentro del boton [X]
cmp dx,0
je botonX
;Si el mouse fue presionado antes del renglon 7
;no hay nada que revisar
cmp dx,7
jb mouse_no_clic
;Si el mouse fue presionado despues del renglon 21
;no hay nada que revisar
cmp dx,21
jg mouse_no_clic
;Si el mouse fue presionado antes de la columna 17
;no hay nada que revisar
cmp cx,17
jb mouse_no_clic
;Si el mouse fue presionado despues de la columna 62
;no hay nada que revisar
cmp cx,62
jg mouse_no_clic
;Si el mouse fue presionado antes de la columna 21 y despues de la 17
;es posible se haya presionado en un boton de base numerica
cmp cx,21
jbe botones_base_num
;Si el mouse fue presionado antes de la columna 24 y despues de la 21
;se presiono en un espacio vacio
cmp cx,24
jb jmp_mouse_no_clic
;Si el mouse fue presionado antes o dentro de la columna 28 y despues de la 24
;revisar si fue dentro de un boton
;Botones entre columnas 24 y 28: '7', '4', '1', 'C'
cmp cx,28
jbe botones_7_4_1_0
; Segunda columna
cmp cx,30
jb jmp_mouse_no_clic
cmp cx,34
jbe botones_8_5_2_A
; Tercer columna
cmp cx,36
jb jmp_mouse_no_clic
cmp cx,40
jbe botones_9_6_3_B
; Cuarta columna
cmp cx,42
jb jmp_mouse_no_clic
cmp cx,46
jbe botones_F_E_D_C
; Quinta columna
cmp cx,51
jb jmp_mouse_no_clic
cmp cx,55
jbe botones_SUM_MUL_MOD
; Sexta columna
cmp cx,57
jb jmp_mouse_no_clic
cmp cx,62
jbe botones_MIN_DIV_EQU
jmp_mouse_no_clic:
jmp mouse_no_clic
botones_base_num:
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton 'Dec'
cmp dx,9
jbe botonDec
cmp dx,10
je mouse_no_clic
cmp dx,13
jbe botonHex
cmp dx,14
je mouse_no_clic
cmp dx,17
jbe botonBin
cmp dx,18
je mouse_no_clic
botones_7_4_1_0:
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton '7'
cmp dx,9
jbe boton7
;renglon 12 es espacio vacio
cmp dx,10
je mouse_no_clic
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton '4'
cmp dx,13
jbe boton4
;renglon 16 es espacio vacio
cmp dx,14
je mouse_no_clic
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton '1'
cmp dx,17
jbe boton1
;renglon 20 es espacio vacio
cmp dx,18
je mouse_no_clic
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton '0'
cmp dx,21
jbe boton0
;Si no es ninguno de los anteriores
jmp mouse_no_clic
; | Agregados los demás botones
botones_8_5_2_A:
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton '8'
cmp dx,9
jbe boton8
;renglon 12 es espacio vacio
cmp dx,10
je mouse_no_clic
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton '5'
cmp dx,13
jbe boton5
;renglon 16 es espacio vacio
cmp dx,14
je mouse_no_clic
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton '2'
cmp dx,17
jbe boton2
;renglon 20 es espacio vacio
cmp dx,18
je mouse_no_clic
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton 'A'
cmp dx,21
jbe botonA
botones_9_6_3_B:
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton '9'
cmp dx,9
jbe boton9
;renglon 12 es espacio vacio
cmp dx,10
je mouse_no_clic
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton '6'
cmp dx,13
jbe boton6
;renglon 16 es espacio vacio
cmp dx,14
je mouse_no_clic
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton '3'
cmp dx,17
jbe boton3
;renglon 20 es espacio vacio
cmp dx,18
je mouse_no_clic
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton 'B'
cmp dx,21
jbe botonB
botones_F_E_D_C:
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton 'F'
cmp dx,9
jbe botonF
;renglon 12 es espacio vacio
cmp dx,10
je mouse_no_clic
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton 'E'
cmp dx,13
jbe botonE
;renglon 16 es espacio vacio
cmp dx,14
je mouse_no_clic
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton 'D'
cmp dx,17
jbe botonD
;renglon 20 es espacio vacio
cmp dx,18
je mouse_no_clic
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton 'C'
cmp dx,21
jbe botonC
botones_SUM_MUL_MOD:
;renglon es espacio vacio
cmp dx,8
jbe mouse_no_clic
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton 'F'
cmp dx,11
jbe botonSuma
;renglon es espacio vacio
cmp dx,12
je mouse_no_clic
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton 'E'
cmp dx,15
jbe botonMult
;renglon es espacio vacio
cmp dx,16
je mouse_no_clic
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton 'D'
cmp dx,19
jbe botonDivR
botones_MIN_DIV_EQU:
;renglon es espacio vacio
cmp dx,8
jbe mouse_no_clic
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton 'F'
cmp dx,11
jbe botonResta
;renglon es espacio vacio
cmp dx,12
je mouse_no_clic
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton 'E'
cmp dx,15
jbe botonDivC
;renglon es espacio vacio
cmp dx,16
je mouse_no_clic
;Revisar si el renglon en donde fue presionado el mouse
;corresponde con boton 'D'
cmp dx,19
jbe botonIgual
;Si no es ninguno de los anteriores
jmp mouse_no_clic
;Dependiendo la posicion del mouse
;se salta a la seccion correspondiente
botonX:
jmp botonX_1
boton0:
jmp boton0_1
boton1:
jmp boton1_1
;===============================================================================;
; Para los botones del 2 al 9, se comprueba primero en qué base está, ya que ;
; pueden ser tanto decimales como hexadecimales. Primero se comprueba si está ;
; en base decimal, en caso de que no esté la selección en decimal, se puede ;
; asumir que tampoco está en hexadecimal, por lo que directamente pasa a ser ;
; un boton deshabilitado. ;
; Si no está seleccionado el modo decimal, se procede a hacer una segunda ;
; comparación, verificando si se está en modo decimal, en caso de que no ;
; esté en modo decimal, directamtente pasa a ser un botón deshabilitado. ;
;===============================================================================;
boton2:
cmp [baseSel],baseHex
je boton2_is_enabled
cmp [baseSel],baseDec
jne mouse_no_clic
boton2_is_enabled:
jmp boton2_1
boton3:
cmp [baseSel],baseHex
je boton3_is_enabled
cmp [baseSel],baseDec
jne mouse_no_clic
boton3_is_enabled:
jmp boton3_1
boton4:
cmp [baseSel],baseHex
je boton4_is_enabled
cmp [baseSel],baseDec
jne mouse_no_clic
boton4_is_enabled:
jmp boton4_1
boton5:
cmp [baseSel],baseHex
je boton5_is_enabled
cmp [baseSel],baseDec
jne mouse_no_clic
boton5_is_enabled:
jmp boton5_1
boton6:
cmp [baseSel],baseHex
je boton6_is_enabled
cmp [baseSel],baseDec
jne mouse_no_clic
boton6_is_enabled:
jmp boton6_1
boton7:
cmp [baseSel],baseHex
je boton7_is_enabled
cmp [baseSel],baseDec
jne mouse_no_clic
boton7_is_enabled:
jmp boton7_1
boton8:
cmp [baseSel],baseHex
je boton8_is_enabled
cmp [baseSel],baseDec
jne mouse_no_clic
boton8_is_enabled:
jmp boton8_1
boton9:
cmp [baseSel],baseHex
je boton9_is_enabled
cmp [baseSel],baseDec
jne mouse_no_clic
boton9_is_enabled:
jmp boton9_1
;===============================================================================;
; En el caso de los botones para hexadecimal (A-F), únicamente se comprueba si ;
; está seleccionado el modo hexadecimal, en caso de que no esté seleccionado, ;
; omite los clicks, ya que son botones deshabilitados. ;
;===============================================================================;
botonA:
cmp [baseSel],baseHex
jne mouse_no_clic
jmp botonA_1
botonB:
cmp [baseSel],baseHex
jne mouse_no_clic
jmp botonB_1
botonC:
cmp [baseSel],baseHex
jne mouse_no_clic
jmp botonC_1
botonD:
cmp [baseSel],baseHex
jne mouse_no_clic
jmp botonD_1
botonE:
cmp [baseSel],baseHex
jne mouse_no_clic
jmp botonE_1
botonF:
cmp [baseSel],baseHex
jne mouse_no_clic
jmp botonF_1
;===============================================================================;
; Para los botones de operaciones, únicamente se pasa el evento del click a ;
; la etiqueta correspondiente. ;
;===============================================================================;
botonSuma:
jmp botonSuma_1
botonResta:
jmp botonResta_1
botonMult:
jmp botonMult_1
botonDivC:
jmp botonDivC_1
botonDivR:
jmp botonDivR_1
botonIgual:
jmp botonIgual_1
;===============================================================================;
; Para cambiar de base, se han agregado cuatro constantes para cada base, como ;
; están declaradas en la sección de datos, estas corresponden a: ;
; 0 - Base Decimal ;
; 1 - Base Hexadecimal ;
; 2 - Base Binaria ;
; Además, se agregó una variable "baseSel", la cual corresponde a la base ;
; seleccionada, esta variable únicamente cambia en esta sección del código. ;
; Una vez seleccionada la base, se limpia la pantalla de la calculadora, y se ;
; marca el botón (o modo) seleccionado. ;
;===============================================================================;
botonDec:
mov [baseSel],baseDec
call LIMPIA_PANTALLA_CALC
jmp mouse_no_clic
botonHex:
mov [baseSel],baseHex
call LIMPIA_PANTALLA_CALC
jmp mouse_no_clic
botonBin:
mov [baseSel],baseBin
call LIMPIA_PANTALLA_CALC
jmp mouse_no_clic
;Logica para revisar si el mouse fue presionado en [X]
;[X] se encuentra en renglon 0 y entre columnas 76 y 79
botonX_1:
cmp cx,76
jge botonX_2
jmp mouse_no_clic
botonX_2:
cmp cx,78
jbe botonX_3
jmp mouse_no_clic
botonX_3:
;Se cumplieron todas las condiciones
jmp salir
;===============================================================================;
; Cada que se presiona un botón, la variable "num_botón" toma el valor de este ;
; y se va directamente a la etiqueta que lee el primer operador. ;
;===============================================================================;
boton0_1:
mov num_boton,0
jmp jmp_lee_oper1
boton1_1:
mov num_boton,1
jmp jmp_lee_oper1
boton2_1:
mov num_boton,2
jmp jmp_lee_oper1
boton3_1:
mov num_boton,3
jmp jmp_lee_oper1
boton4_1:
mov num_boton,4
jmp jmp_lee_oper1
boton5_1:
mov num_boton,5
jmp jmp_lee_oper1
boton6_1:
mov num_boton,6
jmp jmp_lee_oper1
boton7_1:
mov num_boton,7
jmp jmp_lee_oper1
boton8_1:
mov num_boton,8
jmp jmp_lee_oper1
boton9_1:
mov num_boton,9
jmp jmp_lee_oper1
botonA_1:
mov num_boton,10
jmp jmp_lee_oper1
botonB_1:
mov num_boton,11
jmp jmp_lee_oper1
botonC_1:
mov num_boton,12
jmp jmp_lee_oper1
botonD_1:
mov num_boton,13
jmp jmp_lee_oper1
botonE_1:
mov num_boton,14
jmp jmp_lee_oper1
botonF_1:
mov num_boton,15
jmp jmp_lee_oper1
;===============================================================================;
; Para el caso de los botones de los operadores, al dar click en uno de estos, ;
; se le asigna el carácter de la operación que se realizará, y directamente ;
; continúa el programa en espera de la segunda operación. ;
;===============================================================================;
botonSuma_1:
mov operador,"+"
jmp imprime_operador
botonResta_1:
mov operador,"-"
jmp imprime_operador
botonMult_1:
mov operador,"*"
jmp imprime_operador
botonDivC_1:
mov operador,"/"
jmp imprime_operador
botonDivR_1:
mov operador,"%"
jmp imprime_operador
imprime_operador:
mov cl,[operador]
mov [num_impr],cl
mov [ren_aux],4d
mov [col_aux],59d
posiciona_cursor [ren_aux],[col_aux]
imprime_caracter_color [num_impr],bgNegro,cBlanco
jmp mouse_no_clic
;===============================================================================;
; Al dar click en el botón "igual", comienza a convertir todas las entradas en ;
; números que la computadora pueda operar. ;
;===============================================================================;
botonIgual_1:
;Salto auxiliar para hacer un salto más largo
;!===============================================================================;
; Para convertir los dígitos almacenados a números, en ambos
mov bx,offset num1 ; Dirección en memoria del número 1
mov cx,[conta1]
call DIG2DEC
mov [num1h],ax
mov bx,offset num2 ; Dirección en memoria del número 2
mov cx,[conta2]
call DIG2DEC
mov [num2h],ax
mov [resultado],0
mov cx,4d
cmp [operador],"+"
je operacion_sumar
cmp [operador],"-"
je operacion_restar
cmp [operador],"*"
je operacion_multiplicar
cmp [operador],"/"
je operacion_dividir
cmp [operador],"%"
je operacion_modulo
jmp mouse_no_clic
; Salto auxiliar para leer los operadores.
jmp_lee_oper1:
jmp lee_oper1
;===============================================================================;
lee_oper1:
cmp [operador],0 ;compara el valor del operador que puede ser 0, '+', '-', '*', '/', '%'
jne lee_oper2 ;Si el comparador es diferente de 0, entonces lee el segundo numero
cmp [conta1],4 ;compara si el contador para num1 llego al maximo
jae no_lee_num ;si conta1 es mayor o igual a 4, entonces se ha alcanzado el numero de digitos
;y no hace nada
mov al,num_boton ;valor del boton presionado en AL
mov di,[conta1] ;copia el valor de conta1 en registro indice DI
mov [num1+di],al ;num1 es un arreglo de tipo byte
;se utiliza di para acceder el elemento di-esimo del arreglo num1
;se guarda el valor del boton presionado en el arreglo
inc [conta1] ;incrementa conta1 por numero correctamente leido
;Se imprime el numero del arreglo num1 de acuerdo a conta1
xor di,di ;limpia DI para utilizarlo
mov cx,[conta1] ;prepara CX para loop de acuerdo al numero de digitos introducidos
mov [ren_aux],3 ;variable ren_aux para hacer operaciones en pantalla
;ren_aux se mantiene fijo a lo largo del siguiente loop
imprime_num1:
push cx ;guarda el valor de CX en la pila
mov [col_aux],58d ;variable col_aux para hacer operaciones en pantalla
;para recorrer la pantalla al imprimir el numero
sub [col_aux],cl ;Para calcular la columna en donde comienza a imprimir en pantalla de acuerdo a CX
posiciona_cursor [ren_aux],[col_aux] ;Posiciona el cursor en pantalla usando ren_aux y col_aux
mov cl,[num1+di] ;copia el digito en CL
or cl,30h ;Pasa valor ASCII
cmp cl,3Ah
jb imprime_num1_dec
add cl,07h
imprime_num1_dec:
imprime_caracter_color cl,bgNegro,cBlanco ;Imprime caracter en CL, color blanco
inc di ;incrementa DI para recorrer el arreglo num1
pop cx ;recupera el valor de CX al inicio del loop
loop imprime_num1
jmp mouse_no_clic
;===============================================================================;
lee_oper2:
cmp [conta2],4 ;compara si el contador para num2 llego al maximo
jae no_lee_num ;si conta2 es mayor o igual a 4, entonces se ha alcanzado el numero de digitos
;y no hace nada
mov al,num_boton
mov di,[conta2]
mov [num2+di],al
inc [conta2]
xor di,di
mov cx,[conta2]
mov [ren_aux],4
imprime_num2:
push cx
mov [col_aux],58d
sub [col_aux],cl
posiciona_cursor [ren_aux],[col_aux]
mov cl,[num2+di]
or cl,30h
cmp cl,3Ah
jb imprime_num2_dec
add cl,07h
imprime_num2_dec:
imprime_caracter_color cl,bgNegro,cBlanco
inc di
pop cx
loop imprime_num2
no_lee_num:
jmp mouse_no_clic
; TODO : Imprimir operación - Convertir a dígitos
;===============================================================================;
operacion_sumar:
xor dx,dx ; Se establece DX en cero
mov ax,[num1h] ; Se mueve el número 1 a ax
mov bx,[num2h] ; Se mueve el número 2 a bx
adc ax,bx ; Se suma ax + bx
jnc add_no_carry ; Si no hay carry, guarda el resultado en AX
adc dx,0 ; Si hay carry, lo guarda en DX
add_no_carry:
mov [resultado],ax ; Guarda AX en la primera mitad del resultado
mov [resultado + 2],dx ; Guarda DX en la segunda mitad del resutlado
jmp imprime_resultado ; Salto a la impresión del resutlado
operacion_restar:
mov ax,[num1h] ; Se mueve el número 1 a ax
mov bx,[num2h] ; Se mueve el número 2 a bx
sub ax,bx ; Se resta ax - bx
jnc sub_no_carry ; Se comprueba si hubo carry, y en caso de que haya, se agrega el carry
sbb dx,0 ; Se agrega el carry
sub_no_carry:
cmp ax,0h ; Se compara si ax es mayor o igual a cero para la impresión de números negativos
jge sub_pos ; Si es mayor o igual, se imprime el resultado
cmp [baseSel],baseBin ; Se comprueba si la base es binaria, para omitir el neg
je sub_pos ; Si es binario, imprime el resultado
cmp [baseSel],baseHex ; Se comprueba si la base es hexadecimal para omitir el neg
je sub_pos
push ax ; Se guardan ax y dx en la pila
push dx
mov [col_aux],49d ; Se prepara el dígito "-" en la posición indicada para imprimir el signo
mov [ren_aux],5h
mov dl,"-"
mov [num_impr],dl
posiciona_cursor [ren_aux],[col_aux]
imprime_caracter_color [num_impr],bgNegro,cBlanco
pop dx ; Se restauran ax y dx
pop ax
neg ax ; Se obtiene el complemento a 2 de ax para imprimirlo como positivo, pero el signo indicará que es negativo
xor dx,dx ; Limpia dx
sub_pos:
mov [resultado],ax ; Mueve el resultado desde ax
mov [resultado + 2],dx ; Guarda dx en la segunda mitad del resultado
jmp imprime_resultado ; Salto a la impresión del resultado
operacion_multiplicar:
mov ax,[num1h] ; Se mueve el número 1 a ax
mov bx,[num2h] ; Se mueve el número 2 a bx
mul bx ; Muliplica AX * BX
mov [resultado],ax ; Guarda AX en la primera mitad del resultado
mov [resultado + 2],dx ; Guarda BX en la segund mitad del resultado
jmp imprime_resultado
operacion_dividir:
mov ax,[num1h] ; Se mueve el número 1 a ax
mov bx,[num2h] ; Se mueve el número 2 a bx
cmp bx,0h
jle omite_division ; Si se intenta dividir entre cero, se omite la operación y se muestra un mensaje de error
xor dx,dx ; Establece DX en cero para la división
div bx
mov [resultado],ax ; Se mueve AX a la primera mitad del resultado
xor dx,dx ; Se limpia DX
mov [resultado + 2],dx ; Se mueve DX al la segunda mitad del resultado
jmp imprime_resultado
omite_division:
mov [col_aux],16d ; Se preparan las variables auxiliares para mostrar el mensaje
mov [ren_aux],2h
mov bx,offset error_zero; Se guarda en BX la dirección en memoria del mensaje
xor si,si ; Se inicia el índice en cero
mov cx,ez_len - 1 ; Se le resta 1 al índice y se guarda en CX
loop_msg:
mov dl,[bx + si] ; Se recorre cada carácter del mensaje para imprimirlo
mov [num_impr],dl
push ax
push bx
push cx
posiciona_cursor [ren_aux],[col_aux]
imprime_caracter_color [num_impr],bgNegro,cRojo
pop cx
pop bx
pop ax
inc [col_aux] ; Se incrementan el índice y la columna
inc si
loop loop_msg
pause_div0: ; Espera a que se presione enter para seguir la ejecución del programa
mov ax,0800h
int 21h
cmp al,0Dh
jnz pause_div0
call LIMPIA_PANTALLA_CALC; Limpia la interfaz
jmp mouse_no_clic ; Continúa la ejecución
operacion_modulo:
mov ax,[num1h]
mov bx,[num2h]
cmp bx,0h ; De la misma manera que en la división, se revisa que el denominador no sea cero
jle omite_division ; y si es cero, se muestra un mensaje de error.
xor dx,dx
div bx
mov [resultado],dx
xor dx,dx
mov [resultado + 2],dx
jmp imprime_resultado
imprime_resultado:
mov [ren_aux],5
cmp [baseSel],baseHex
je imprime_resultado_hex
cmp [baseSel],baseDec
je imprime_resultado_dec