-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathzbior_julii.asm
777 lines (557 loc) · 13.1 KB
/
zbior_julii.asm
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
dane1 segment
args db 256 dup('$')
arg_start db 128 dup(0) ;n-ty bajt to indeks poczatku n-tego arg.
arg_length db 128 dup(0) ;dlugosc n-tego arg.
arg_num db 0
xmin dq ?
xmax dq ?
ymin dq ?
ymax dq ?
cr dq ?
ci dq ?
four dq 4.0
ten dq 10.0
tenth dq 0.1
minus dq -1.0
NMAX dq 320.0
MMAX dq 200.0
x DQ ? ;23.5
y DQ ? ;17.2
digit dw ?
tmp dq ?
dane1 ends
code1 segment
xx dw 60
yy dw 80
kol dw 15
is_negative db 0
temp dw 0
start1:
.386
.387
mov sp, offset wstosu
mov ax, seg wstosu
mov ss, ax
xor bx,bx
mov bl,byte ptr ds:[080h]
dec bl
mov cx,bx
call eat_all
finit
call args_to_double
call graph_mode
call draw
call wait_for_key
call text_mode
exit:
mov ah,4ch
int 021h
;===============================================================================
;PARSER
;===================================================================================
eat_all:
; brak parametrow
push ax
push bx
push es
push si
push bp
mov ax,seg arg_start
mov es,ax
mov si,offset arg_start ;wspolrzedne poczatkow slow
mov byte ptr es:[si],0 ;pierwszy arg. zaczyna sie w 0
mov ax,seg args
mov es,ax ;tu beda argumenty oddzielone spacjami
mov si,offset args
mov bp,0 ;indeks aktualnie wczytywanego znaku
eat_all_l: ;WCZYTAJ
call eat_spaces ;zjedz spacje
cmp bx,bp ;czy to koniec?
jle eat_all_f
call eat_arg ;zjedz kolejny argument
cmp bx,bp ;czy to koniec?
jle eat_all_f
jmp eat_all_l ;petla
eat_all_f:
pop bp
pop si
pop es
pop bx
pop ax
ret
eat_arg:
; kopiuje do stringa argument do bialego znaku
;PARAMETRY:
; bp - indeks wczytywanego znaku
; ds - segment programu (parametry)
; si - indeks docelowy w stringu args
; es - segment args
; cx - ile znakow zostalo do wczytania
;ZWRACA:
; cx, bp, si - aktualne
eat_arg_l:
cmp byte ptr ds:[082h+bp]," " ;bialy znak - koniec argumentu
jz eat_arg_f
cmp byte ptr ds:[082h+bp],09h ;tab
jz eat_arg_f
mov al, byte ptr ds:[082h+bp] ;aktualny znak do al
mov byte ptr es:[si],al ;zapisz znak w stringu
inc bp
inc si ;indeksy do przodu
loop eat_arg_l
eat_arg_f:
mov byte ptr es:[si]," " ; dodaj separator " "
inc si ; si ma indeks pierwszego znaku nast. arg.
call inc_arg_num
ret
eat_spaces:
; pomin biale znaki
;PARAMETRY:
; bp - dany znak parametru
; ds - segment programu (parametry)
; cx - ile znakow zostalo do wczytania
;ZWRACA:
; bp, cx - aktualne
eat_s_l:
cmp byte ptr ds:[082h+bp]," " ;czy to bialy znak?
jz eat_s_continue
cmp byte ptr ds:[082h+bp],09h ;tab
jz eat_s_continue
jmp eat_s_f ;nie, to nie bialy znak
eat_s_continue:
inc bp ;pomin ten znak
loop eat_s_l
eat_s_f:
ret
inc_arg_num:
; zwieksza arg_num po zjedzeniu arg., zapisuje jego dlugosc
;PARAMETRY:
; zmienna arg_num - dotychczasowa l. arg.
push ax
push bx
push si
push es
xor ax,ax
mov bx,seg arg_num ;zwieksz liczbe arg.
mov es,bx
mov bx,offset arg_num
mov al,byte ptr es:[bx]
inc al
mov byte ptr es:[bx],al ;al - liczba wczytanych dotad arg.
mov bx,seg arg_start
mov es,bx
mov bx,offset arg_start
add bx,ax ;nakierowanie na al-ty el. tablicy
push ax ;bo numer tego arg. sie jeszcze przyda
mov ax,si ;si - indeks pierwszego znaku arg. w stringu
mov byte ptr es:[bx],al ;zapisz poczatek arg.
;spokojnie, nie przekroczy wart. 127 (ah=0)
mov al,byte ptr es:[bx-1] ;ax ma poczatek poprzedniego arg.
sub si,ax ;si = roznica-1 = dlugosc
dec si ;si zawiera dlugosc danego arg.
pop ax ;ax znowu ma numer arg.
mov bx,seg arg_length
mov es,bx
mov bx,offset arg_length ; es:[bx] - tablica dlugosci
add bx,ax ; ax-ty el.
dec bx ; -1, zeby sie zgadzalo
mov ax,si ; si to dlugosc arg.
mov byte ptr es:[bx],al ; al bo 8bit
pop es
pop si
pop bx
pop ax
ret
;============================================================================
get_arg_start:
;PARAMETRY: ax - indeks arg., od 0
;ZWRACA: es - seg args
; si - offset tego arg.
push ax
push bx
mov bx,seg arg_start
mov es,bx
mov si,offset arg_start ;znajdz poczatek tego arg.
xor bx,bx
add si,ax ;przesun na ax-ty element arg_start
mov bl,byte ptr es:[si] ; bl - ind. pierwszego znaku tego arg.
mov ax,seg args
mov es,ax
mov si,offset args
add si,bx ;ustaw si na pierwszym znaku tego arg.
pop bx
pop ax
ret
get_arg_len:
;PARAMETRY: ax - indeks arg., od 0
;ZWRACA: bx - dlugosc arg.
push ax
push es
push si
mov bx,seg arg_length
mov es,bx
mov si,offset arg_length ;znajdz poczatek tego arg.
add si,ax ;przesun na ax-ty element arg_length
xor bh,bh
mov bl,byte ptr es:[si]
pop si
pop es
pop ax
ret
;==========================================================================
;
; ARGS TO DOUBLE
;
;==========================================================================
args_to_double:
; wczytuje argumenty do pamieci
push ax
push es
push si
xor ax,ax
call arg_to_double
push ax
mov ax,seg xmin
mov es,ax
mov si, offset xmin
fstp qword ptr es:[si]
pop ax
call arg_to_double
push ax
mov ax,seg xmax
mov es,ax
mov si, offset xmax
fstp qword ptr es:[si]
pop ax
call arg_to_double
push ax
mov ax,seg ymin
mov es,ax
mov si, offset ymin
fstp qword ptr es:[si]
pop ax
call arg_to_double
push ax
mov ax,seg ymax
mov es,ax
mov si, offset ymax
fstp qword ptr es:[si]
pop ax
call arg_to_double
push ax
mov ax,seg cr
mov es,ax
mov si, offset cr
fstp qword ptr es:[si]
pop ax
call arg_to_double
push ax
mov ax,seg ci
mov es,ax
mov si, offset ci
fstp qword ptr es:[si]
pop ax
pop si
pop es
pop ax
ret
arg_to_double:
;PARAMETRY: ax - indeks arg. (inkrementowany przy kazdym obiegu)
;ZWRACA: wczytana liczba na gorze stosu FPU
push ax
push bx
push es
push si
call get_arg_start
call get_arg_len
;es - seg, si - offset poczatku arg.
;bx - dlugosc arg.
call parse_double
pop si
pop es
pop bx
pop ax
inc ax
ret
;========================================================================
;
; PARSE TO DOUBLE
;
;========================================================================
parse_double:
;PARAMETRY: es:si - adres poczatku danego parametru wywolania
; bx - dlugosc tego arg.
;1) ALL ?
;2) double | ?
call parse_minus ;sprawdz pierwszy znak
push si
call parsef1 ;przed kropka
fstp st(1) ;na st1 bylo 10
pop si
call parsef2 ;po kropce
fstp st(1) ;na st1 bylo 0.1
faddp st(1), st ;dodajemy czesc calk. do ulamkowej
call add_minus ;jesli flaga ustawiona, pomnoz przez -1
ret
parse_minus:
;ustawia flage na 1 jesli jest minus
push ax
push es
mov byte ptr cs:[is_negative],0
cmp byte ptr es:[si],"-"
jne parse_minus_f
mov byte ptr cs:[is_negative],1
inc si ;na pierwsza cyfre
parse_minus_f:
pop es
pop ax
ret
add_minus:
push ax
push es
push si
cmp byte ptr cs:[is_negative],1
jne add_minus_f
mov ax,seg minus
mov es,ax
mov si, offset minus
fld qword ptr es:[si]
fmulp st(1),st
add_minus_f:
pop si
pop es
pop ax
ret
parsef1:
;1) ALL ?
;2) czesc calkowita | 10 | ?
push es
push si
mov ax,seg ten
mov es,ax
mov si, offset ten
fld qword ptr es:[si]
fldz
pop si
pop es
parse_digit_l1:
xor ch,ch
mov cl,byte ptr es:[si]
cmp cl,"."
jz parse_digit_f1
fmul st, st(1)
sub cx, "0"
mov cs:[temp],cx
fild word ptr cs:[temp]
faddp st(1), st
inc si ;nie mozna zrobic osobnej procedury, bo tu inc a tam dec!
;i tu mnozymy przed, a tam po
jmp parse_digit_l1
parse_digit_f1:
ret
parsef2:
;1) czesc calkowita | ?
;2) czesc ulamkowa | 0.1 | czesc calk. | ?
push es
push si
cmp byte ptr cs:[is_negative],1
jne parsef2_moving_f
dec bx ;jesli byl minus, popraw dlugosc arg.
parsef2_moving_f:
mov ax,seg tenth
mov es,ax
mov si, offset tenth
fld qword ptr es:[si]
fldz
pop si
pop es
dec bx
add si,bx
parse_digit_l2:
xor ch,ch
mov cl,byte ptr es:[si]
cmp cl,"."
jz parse_digit_f2
sub cx, "0"
mov cs:[temp],cx
fild word ptr cs:[temp]
faddp st(1), st
fmul st, st(1)
dec si
jmp parse_digit_l2
parse_digit_f2:
ret
;============================================================================
; MAGIA
;============================================================================
calc:
push ax
push cx
push es
push si
mov ax,seg ci
mov es,ax
mov si,offset ci
fld qword ptr es:[si] ; ci
mov ax,seg cr
mov es,ax
mov si,offset cr
fld qword ptr es:[si] ; cr | ci
call calc_zi ; y=zi | cr | ci
call calc_zr ; x=zr | y=zi | cr | ci
fld st ; x | x | y | cr | ci
fld st ; x | x | x | y | cr | ci
fmulp st(1), st ; x2 | x | y | cr | ci
fld st(2) ; y | x2 | x | y | cr | ci
fld st ; y | y | x2 | x | y | cr | ci
fmulp st(1), st ; y2 | x2 | x | y | cr | ci
mov cx,1000d
calc_l:
fsubp st(1), st ; x2-y2 | x | y | cr | ci
fld st(3) ; cr | x2-y2 | x | y | cr | ci
faddp st(1), st ; tmp = x2-y2+cr | x | y | cr | ci
fxch st(2) ; y | x | tmp | cr | ci
fld st ; y | y | x | tmp | cr | ci
faddp st(1), st ; 2y | x | tmp | cr | ci
fmulp st(1), st ; 2xy | x=tmp | cr | ci
fld st(3) ; ci | 2xy | x=tmp | cr | ci
faddp st(1), st ; y=2xy+ci | x | cr | ci
fxch st(1) ; x | y | cr | ci
fld st ; x | x | y | cr | ci
fmul st, st(1) ; x2 | x | y | cr | ci
fld st ; x2 | x2 | x | y | cr | ci
fld st(3) ; y | x2 | x2 | x | y | cr | ci
fld st ; y | y | x2 | x2 | x | y | cr | ci
fmulp st(1), st ; y2 | x2 | x2 | x | y | cr | ci
fxch st(1) ; x2 | y2 | x2 | x | y | cr | ci
fadd st, st(1) ; x2+y2 | y2 | x2 | x | y | cr | ci
mov ax,seg four
mov es,ax
mov si,offset four
fild qword ptr es:[si] ; 4 | x2+y2 | y2 | x2 | x | y | cr | ci
fcomp ; x2+y2 | y2 | x2 | x | y | cr | ci
fstsw ax
sahf
jb calc_break
fstp st ; y2 | x2 | x | y | cr | ci
loop calc_l
calc_ok:
mov byte ptr cs:[kol],0h
jmp calc_done
calc_break:
sub cl,50h
mov byte ptr cs:[kol],cl
jmp calc_done
calc_done:
pop si
pop es
pop cx
pop ax
ret
calc_zr:
push ax
push es
push si
mov ax,seg xmax
mov es,ax
mov si,offset xmax
fld qword ptr es:[si]
mov ax,seg xmin
mov es,ax
mov si,offset xmin
fld qword ptr es:[si]
fsubp st(1),st
mov ax,seg NMAX
mov es,ax
mov si,offset NMAX
fld qword ptr es:[si]
fdivp st(1),st
fild word ptr cs:[xx]
fmulp st(1),st
mov ax,seg xmin
mov es,ax
mov si,offset xmin
fld qword ptr es:[si]
faddp st(1),st
pop si
pop es
pop ax
ret
calc_zi:
push ax
push es
push si
mov ax,seg ymax
mov es,ax
mov si,offset ymax
fld qword ptr es:[si]
mov ax,seg ymin
mov es,ax
mov si,offset ymin
fld qword ptr es:[si]
fsubp st(1),st
mov ax,seg MMAX
mov es,ax
mov si,offset MMAX
fld qword ptr es:[si]
fdivp st(1),st
fild word ptr cs:[yy]
fmulp st(1),st
mov ax,seg ymin
mov es,ax
mov si,offset ymin
fld qword ptr es:[si]
faddp st(1),st
pop si
pop es
pop ax
ret
draw:
mov word ptr cs:[yy],0
mov cx,200
rows_l:
push cx
mov word ptr cs:[xx],0
mov cx,320
cols_l:
call calc
call zapal_punkt
inc word ptr cs:[xx]
loop cols_l
pop cx
inc word ptr cs:[yy]
loop rows_l
ret
zapal_punkt:
mov ax,0a000h ;adres segm pam. obrazu
mov es,ax
mov ax,word ptr cs:[yy]
mov bx,320
mul bx ; dx:ax = ax * bx
add ax,word ptr cs:[xx] ;ax = 320*y +x
mov bx,ax
mov al,byte ptr cs:[kol]
mov byte ptr es:[bx],al
ret
graph_mode:
mov al,13h ;tryb graficzny 320x200 punktow 256 kolorow
mov ah,0
int 10h
ret
text_mode:
mov al,3h ;tryb tekstowy
xor ah,ah
int 10h
ret
wait_for_key:
xor ax,ax
int 16h ;czekaj na dow. klawisz
ret
;============================================================================
;=============================================================================
code1 ends
stos1 segment stack
dw 400 dup(?)
wstosu dw ?
stos1 ends
end start1