forked from microsoft/GW-BASIC
-
Notifications
You must be signed in to change notification settings - Fork 0
/
NEXT86.ASM
160 lines (154 loc) · 4.38 KB
/
NEXT86.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
; [ This translation created 10-Feb-83 by Version 4.3 ]
.RADIX 8 ; To be safe
CSEG SEGMENT PUBLIC 'CODESG'
ASSUME CS:CSEG
INCLUDE OEM.H
TITLE NEXT86 CODE
.SALL
.RADIX 8
;****************************************************************
;
; A "FOR" ENTRY ON THE STACK HAS THE FOLLOWING FORMAT:
;
; LOW ADDRESS
; TOKEN ($FOR IN HIGH BYTE) 1 BYTES
; A POINTER TO THE LOOP VARIABLE 2 BYTES
; UNDER ANSI & LENGTH=2, TWO BYTES GIVING TEXT POINTER OF
; MATCHING "NEXT"
; A BYTE REFLECTING THE SIGN OF THE INCREMENT 1 BYTE
; UNDER LENGTH=2, A BYTE MINUS FOR INTEGER AND
; POSITIVE FOR FLOATING "FOR'S"
; THE STEP 4 BYTES
; THE UPPER VALUE 4 BYTES
; THE LINE # OF THE "FOR" STATEMENT 2 BYTES
; A TEXT POINTER INTO THE "FOR" STATEMENT 2 BYTES
; HIGH ADDRESS
;
; TOTAL 16-19 BYTES
;
;*****************************************************************
EXTRN CHRGTR:NEAR,DCOMPR:NEAR,FADDS:NEAR,FCOMP:NEAR,FNDFOR:NEAR
EXTRN IADD:NEAR
EXTRN ICMPA:NEAR,MOVFM:NEAR,MOVMF:NEAR,MOVRM:NEAR,NEWSTT:NEAR
EXTRN NFERR:NEAR,NXTCON:NEAR,OVERR:NEAR
EXTRN PTRGET:NEAR
PUBLIC NEXT
PUBLIC NEXTS
DSEG SEGMENT PUBLIC 'DATASG'
ASSUME DS:DSEG
EXTRN NXTFLG:WORD,FVALSV:WORD,NXTTXT:WORD
DSEG ENDS
DSEG SEGMENT PUBLIC 'DATASG'
EXTRN FACLO:WORD,SAVSTK:WORD,TEMP:WORD,VALTYP:WORD,CURLIN:WORD
DSEG ENDS
NF1: JMP NFERR
NEXT:
LAHF ;FLAGS TO AH
XCHG AH,AL
PUSH AX
MOV AL,LOW 1
JMP SHORT NEXTS1
NEXTS: XOR AL,AL ;FLAG THAT "FOR IS USING "NEXT
NEXTS1: MOV BYTE PTR NXTFLG,AL
POP AX
XCHG AL,AH
SAHF
MOV DX,0
NEXTC:
MOV WORD PTR NXTTXT,BX ;SAVE STARTING TEXT POINTER
JZ NEXTC1
CALL PTRGET
NEXTC1: MOV WORD PTR TEMP,BX ;SAVE PTR TO LOOP VARIABLE
CALL FNDFOR ;TRY TO FING A "FOR ENTRY
JNZ NF1 ;NEXT W/O FOR ERROR
MOV SP,BX ;SETUP STACK BY CHOPPING HERE
MOV SI,WORD PTR NXTTXT
CMP WORD PTR 0[BX],SI ;COMPARE TEXT POINTERS AT THE START
JNZ NF1 ;OF THIS "NEXT WITH THIS NEXT
PUSH DX ;PUSH STEP ONTO THE STACK
MOV AH,BYTE PTR 2[BX] ;
PUSH AX
PUSH DX ;PTR. TO LOOP VAR. ON STACK
ADD BX,4
TEST BYTE PTR -1[BX],LOW 200O ;SEE IF INTEGER FOR
JS INTNXT ;IF INTEGER HANDLE SEPARATELY
MOV CX,2 ;
CLD ;DF=0 SO MOVW WILL INCREMENT
MOV SI,BX
MOV DI,OFFSET FACLO
REP MOVSW ;GET LOOP VARIABLE
POP BX ;PTR TO FOR ENTRY
PUSH SI ;
PUSH BX
TEST BYTE PTR NXTFLG,LOW 377O
JNZ NXTDO
MOV SI,OFFSET FVALSV ;FETCH INITIAL VALUE
SUB DI,4 ;POINT DI BACK TO FACLO
MOV CX,2 ;TWO WORD MOVE
REP MOVSW
XOR AL,AL ;CONTINUE "NEXT" WITH INITIAL VALUE
JZ NXTDOA ;
NXTDO: CALL FADDS
NXTDOA: POP DI ;POP PTR TO LOOP VARIABLE
MOV SI,OFFSET FACLO ;WILL MOVE FAC TO THERE
MOV CX,2
CLD
REP MOVSW
POP SI ;GET ENTRY PTR.
MOV DX,WORD PTR 0[SI]
MOV CX,WORD PTR 2[SI]
ADD SI,4
PUSH SI ;SAVE ENTRY PTR.
CALL FCOMP ;COMPARE THE NOS. RETURNING
;377 IF FAC LESS THAN REGS,0 IF =
;AND 1 IF GREATER
JMP SHORT FINNXT ;SKIP INTEGER CODE
INTNXT: ADD BX,4 ;SKIP 4 DUMMY BYTES
MOV CX,WORD PTR 0[BX] ;FETCH STEP TO CX
INC BX
INC BX
POP SI ;PTR TO LOOP VARIABLE
MOV DX,WORD PTR 0[SI]
TEST BYTE PTR NXTFLG,LOW 377O ;SEE IF "FOR IS USING "NEXT CODE
JNZ INXTDO ;NO , JUST CONTINUE
MOV DX,WORD PTR FVALSV ;GET THE INITIAL VALUE
JMP SHORT IFORIN ;CONTINUE FIRST ITERATION CHECK
INXTDO: ADD DX,CX
JO OV1
IFORIN:
MOV WORD PTR 0[SI],DX
PUSH DX ;SAVE THE VALUE OF THE LOOP VAR.
MOV DX,WORD PTR 0[BX] ;
INC BX
INC BX
POP AX
PUSH BX
CALL ICMPA ;COMPARE (AX) WITH (DX)
FINNXT:
POP BX ;POP "FOR ENTRY PTR
POP CX ;GET SGN OF INCREMENT
SUB AL,CH ;SUBTRACT THE INCREMENTS SIGN FROM
;THAT OF (CURRENT VAL-FINAL VAL)
CALL MOVRM ;GET LINE # OF "FOR INTO DX AND
;TEXT PTR OF "FOR INTO CX
JZ LOOPDN ;JUMP IF DONE
MOV WORD PTR CURLIN,DX ;STORE LINE NO.
MOV DX,CX ;SETUP THE TEXT PTR
XCHG DX,BX
JMP NXTCON
LOOPDN: MOV SP,BX ;ELIMINATE FOR ENTRY & SAVE UPDATED
MOV WORD PTR SAVSTK,BX ;STACK
MOV BX,WORD PTR TEMP ;RESTORE TEXT PTR
CMP BYTE PTR 0[BX],LOW 54O ;COMMA?
JNZ NS1 ;"NEXT
LOOPD1: MOV BYTE PTR NXTFLG,LOW 377O ;Set NXTFLG non-zero since NEXT couldn't
;have been called by FOR in this case
CALL CHRGTR ;Skip comma
MOV DX,SP ;[DX]=[SP] which will never match
;any VARPTR (see FNDFOR)
CALL NEXTC ;Process Next NEXT
OV1: JMP OVERR
NS1: JMP NEWSTT
CSEG ENDS
END