summaryrefslogtreecommitdiff
path: root/v2.0/source/TCODE2.ASM
blob: bc2742d90ed7650ac60522f1e78c1e06896ab304 (plain) (blame)
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
TITLE   PART2 - COMMAND Transient routines.

        INCLUDE COMSW.ASM

.xlist
.xcref
        INCLUDE DOSSYM.ASM
        INCLUDE DEVSYM.ASM
        INCLUDE COMSEG.ASM
.list
.cref

        INCLUDE COMEQU.ASM

CODERES SEGMENT PUBLIC
        EXTRN   LODCOM1:NEAR
CODERES ENDS

DATARES SEGMENT PUBLIC
        EXTRN   PARENT:WORD,IO_SAVE:WORD,PERMCOM:BYTE
        EXTRN   PIPEFLAG:BYTE,ENVIRSEG:WORD
        if      ibmver
        EXTRN   SYS_CALL:DWORD
        endif
DATARES ENDS

TRANDATA        SEGMENT PUBLIC

        EXTRN   PATH_TEXT:BYTE,PROMPT_TEXT:BYTE
        EXTRN   BADDEV:BYTE,SYNTMES:BYTE,ENVERR:BYTE
TRANDATA        ENDS

TRANSPACE       SEGMENT PUBLIC

        EXTRN   CURDRV:BYTE,DIRCHAR:BYTE,PWDBUF:BYTE
        EXTRN   INTERNATVARS:BYTE,RESSEG:WORD,TPA:WORD

TRANSPACE       ENDS


TRANCODE        SEGMENT PUBLIC BYTE
ASSUME  CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING

        EXTRN   CERROR:NEAR,ZPRINT:NEAR
        EXTRN   CRLF2:NEAR,SCANOFF:NEAR,FREE_TPA:NEAR,ALLOC_TPA:NEAR
        EXTRN   OUT:NEAR,DRVBAD:NEAR,SETPATH:NEAR,PRINT:NEAR
        EXTRN   FCB_TO_ASCZ:NEAR

        PUBLIC  PRINT_DRIVE,$EXIT,MOVE_NAME
        PUBLIC  UPCONV,ADD_PROMPT,CTTY,PRINT_DEFAULT_DIRECTORY
        PUBLIC  ADD_NAME_TO_ENVIRONMENT,PWD,SCAN_DOUBLE_NULL
        PUBLIC  FIND_NAME_IN_ENVIRONMENT,STORE_CHAR
        PUBLIC  FIND_PATH,DELETE_PATH,FIND_PROMPT
        PUBLIC  SCASB2

        IF      KANJI
        PUBLIC  TESTKANJ
        ENDIF

BREAK   <Environment utilities>
ASSUME DS:TRANGROUP

ADD_PROMPT:
        CALL    DELETE_PROMPT                   ; DELETE ANY EXISTING PROMPT
        CALL    SCAN_DOUBLE_NULL
ADD_PROMPT2:
        PUSH    SI
        CALL    GETARG
        POP     SI
        retz                                    ; PRE SCAN FOR ARGUMENTS
        CALL    MOVE_NAME                       ; MOVE IN NAME
        CALL    GETARG
        JMP     SHORT ADD_NAME
;
; Input: DS:SI points to a CR terminated string
; Output: carry flag is set if no room
;         otherwise name is added to environment
;
ADD_NAME_TO_ENVIRONMENT:
        CALL    GETARG
        JZ      DISP_ENV
;
; check if line contains exactly one equals sign
;
        XOR     BX,BX           ;= COUNT IS 0
        PUSH    SI              ;SAVE POINTER TO BEGINNING OF LINE
EQLP:
        LODSB                   ;GET A CHAR
        CMP     AL,13           ;IF CR WE'RE ALL DONE
        JZ      QUEQ
        CMP     AL,"="          ;LOOK FOR = SIGN
        JNZ     EQLP            ;NOT THERE, GET NEXT CHAR
        INC     BL              ;OTHERWISE INCREMENT EQ COUNT
        CMP     BYTE PTR [SI],13        ;LOOK FOR CR FOLLOWING = SIGN
        JNZ     EQLP
        INC     BH              ;SET BH=1 MEANS NO PARAMETERS
        JMP     EQLP            ;AND LOOK FOR MORE
QUEQ:
        POP     SI              ;RESTORE BEGINNING OF LINE
        DEC     BL              ;ZERO FLAG MEANS ONLY ONE EQ
        JZ      ONEQ            ;GOOD LINE
        MOV     DX,OFFSET TRANGROUP:SYNTMES
        JMP     CERROR

ONEQ:
        PUSH    BX
        CALL    DELETE_NAME_IN_ENVIRONMENT
        POP     BX
        DEC     BH
        retz

        CALL    SCAN_DOUBLE_NULL
        CALL    MOVE_NAME
ADD_NAME:
        LODSB
        CMP     AL,13
        retz
        CALL    STORE_CHAR
        JMP     ADD_NAME

DISP_ENV:
        MOV     DS,[RESSEG]
ASSUME  DS:RESGROUP
        MOV     DS,[ENVIRSEG]
ASSUME  DS:NOTHING
        XOR     SI,SI
PENVLP:
        CMP     BYTE PTR [SI],0
        retz

        MOV     DX,SI
        CALL    ZPRINT
        CALL    CRLF2
PENVLP2:
        LODSB
        OR      AL,AL
        JNZ     PENVLP2
        JMP     PENVLP

ASSUME  DS:TRANGROUP
DELETE_PATH:
        MOV     SI,OFFSET TRANGROUP:PATH_TEXT
        JMP     SHORT DELETE_NAME_IN_environment

DELETE_PROMPT:
        MOV     SI,OFFSET TRANGROUP:PROMPT_TEXT

DELETE_NAME_IN_environment:
;
; Input: DS:SI points to a "=" terminated string
; Output: carry flag is set if name not found
;         otherwise name is deleted
;
        PUSH    SI
        PUSH    DS
        CALL    FIND            ; ES:DI POINTS TO NAME
        JC      DEL1
        MOV     SI,DI           ; SAVE IT
        CALL    SCASB2          ; SCAN FOR THE NUL
        XCHG    SI,DI
        CALL    GETENVSIZ
        SUB     CX,SI
        PUSH    ES
        POP     DS              ; ES:DI POINTS TO NAME, DS:SI POINTS TO NEXT NAME
        REP     MOVSB           ; DELETE THE NAME
DEL1:
        POP     DS
        POP     SI
        return

FIND_PATH:
        MOV     SI,OFFSET TRANGROUP:PATH_TEXT
        JMP     SHORT FIND_NAME_IN_environment

FIND_PROMPT:
        MOV     SI,OFFSET TRANGROUP:PROMPT_TEXT

FIND_NAME_IN_environment:
;
; Input: DS:SI points to a "=" terminated string
; Output: ES:DI points to the arguments in the environment
;         zero is set if name not found
;         carry flag is set if name not valid format
;
        CALL    FIND                    ; FIND THE NAME
        retc                            ; CARRY MEANS NOT FOUND
        JMP     SCASB1                  ; SCAN FOR = SIGN
;
; On return of FIND1, ES:DI points to beginning of name
;
FIND:
        CLD
        CALL    COUNT0                  ; CX = LENGTH OF NAME
        MOV     ES,[RESSEG]
ASSUME  ES:RESGROUP
        MOV     ES,[ENVIRSEG]
ASSUME  ES:NOTHING
        XOR     DI,DI
FIND1:
        PUSH    CX
        PUSH    SI
        PUSH    DI
FIND11:
        LODSB

        IF      KANJI
        CALL    TESTKANJ
        JZ      NOTKANJ3
        DEC     SI
        LODSW
        INC     DI
        INC     DI
        CMP     AX,ES:[DI-2]
        JNZ     FIND12
        DEC     CX
        LOOP    FIND11
        JMP     SHORT FIND12

NOTKANJ3:
        ENDIF

        CALL    UPCONV
        INC     DI
        CMP     AL,ES:[DI-1]
        JNZ     FIND12
        LOOP    FIND11
FIND12:
        POP     DI
        POP     SI
        POP     CX
        retz
        PUSH    CX
        CALL    SCASB2                  ; SCAN FOR A NUL
        POP     CX
        CMP     BYTE PTR ES:[DI],0
        JNZ     FIND1
        STC                             ; INDICATE NOT FOUND
        return

COUNT0:
        PUSH    DS
        POP     ES
        MOV     DI,SI

COUNT1:
        PUSH    DI                      ; COUNT NUMBER OF CHARS UNTIL "="
        CALL    SCASB1
        JMP     SHORT COUNTX
COUNT2:
        PUSH    DI                      ; COUNT NUMBER OF CHARS UNTIL NUL
        CALL    SCASB2
COUNTX:
        POP     CX
        SUB     DI,CX
        XCHG    DI,CX
        return

MOVE_NAME:
        CMP     BYTE PTR DS:[SI],13
        retz
        LODSB

        IF      KANJI
        CALL    TESTKANJ
        JZ      NOTKANJ1
        CALL    STORE_CHAR
        LODSB
        CALL    STORE_CHAR
        JMP     SHORT MOVE_NAME

NOTKANJ1:
        ENDIF

        CALL    UPCONV
        CALL    STORE_CHAR
        CMP     AL,"="
        JNZ     MOVE_NAME
        return

GETARG:
        MOV     SI,80H
        LODSB
        OR      AL,AL
        retz
        CALL    SCANOFF
        CMP     AL,13
        return

SCAN_DOUBLE_NULL:
        MOV     ES,[RESSEG]
ASSUME  ES:RESGROUP
        MOV     ES,[ENVIRSEG]
ASSUME  ES:NOTHING
        XOR     DI,DI
SDN1:
        CALL    SCASB2
        CMP     BYTE PTR ES:[DI],0
        JNZ     SDN1
        return

SCASB1:
        MOV     AL,"="                  ; SCAN FOR AN =
        JMP     SHORT SCASBX
SCASB2:
        XOR     AL,AL                   ; SCAN FOR A NUL
SCASBX:
        MOV     CX,100H
        REPNZ   SCASB
        return

        IF      KANJI
TESTKANJ:
        CMP     AL,81H
        JB      NOTLEAD
        CMP     AL,9FH
        JBE     ISLEAD
        CMP     AL,0E0H
        JB      NOTLEAD
        CMP     AL,0FCH
        JBE     ISLEAD
NOTLEAD:
        PUSH    AX
        XOR     AX,AX           ;Set zero
        POP     AX
        return

ISLEAD:
        PUSH    AX
        XOR     AX,AX           ;Set zero
        INC     AX              ;Reset zero
        POP     AX
        return
        ENDIF

UPCONV:
        CMP     AL,"a"
        JB      RET22C
        CMP     AL,"z"
        JA      RET22C
        SUB     AL,20H          ; Lower-case changed to upper-case
RET22C:
        CALL    DWORD PTR CS:[INTERNATVARS.Map_call]
        return
;
; STORE A CHAR IN environment, GROWING IT IF NECESSARY
;
STORE_CHAR:
        PUSH    CX
        PUSH    BX
        CALL    GETENVSIZ
        MOV     BX,CX
        SUB     BX,2            ; SAVE ROOM FOR DOUBLE NULL
        CMP     DI,BX
        JB      STORE1

        PUSH    AX
        PUSH    CX
        PUSH    BX              ; Save Size of environment
        CALL    FREE_TPA
        POP     BX
        ADD     BX,2            ; Recover true environment size
        MOV     CL,4
        SHR     BX,CL           ; Convert back to paragraphs
        INC     BX              ; Try to grow environment by one para
        MOV     AH,SETBLOCK
        INT     int_command
        PUSHF
        PUSH    ES
        MOV     ES,[RESSEG]
        CALL    ALLOC_TPA
        POP     ES
        POPF
        POP     CX
        POP     AX
        JNC     STORE1
        MOV     DX,OFFSET TRANGROUP:ENVERR
        JMP     CERROR
STORE1:
        STOSB
        MOV     WORD PTR ES:[DI],0            ; NULL IS AT END
        POP     BX
        POP     CX
        return

GETENVSIZ:
;Get size of environment in bytes, rounded up to paragraph boundry
;ES has environment segment
;Size returned in CX, all other registers preserved

        PUSH    ES
        PUSH    AX
        MOV     AX,ES
        DEC     AX              ;Point at arena
        MOV     ES,AX
        MOV     AX,ES:[arena_size]
        MOV     CL,4
        SHL     AX,CL           ;Convert to bytes
        MOV     CX,AX
        POP     AX
        POP     ES
        return

PRINT_DRIVE:
        MOV     AH,GET_DEFAULT_DRIVE
        INT     int_command
        ADD     AL,"A"
        JMP     OUT

ASSUME  DS:TRANGROUP,ES:TRANGROUP
PWD:
        CALL    PRINT_DIRECTORY
        CALL    CRLF2
        return

PRINT_DEFAULT_DIRECTORY:
        MOV     BYTE PTR DS:[FCB],0
PRINT_DIRECTORY:
        MOV     DL,DS:[FCB]
        MOV     AL,DL
        ADD     AL,'@'
        CMP     AL,'@'
        JNZ     GOTDRIVE
        ADD     AL,[CURDRV]
        INC     AL
GOTDRIVE:
        PUSH    AX
        MOV     SI,OFFSET TRANGROUP:PWDBUF+3
        MOV     AH,CURRENT_DIR
        INT     int_command
        JNC     DPBISOK
        PUSH    CS
        POP     DS
        JMP     DRVBAD
DPBISOK:
        MOV     DI,OFFSET TRANGROUP:PWDBUF
        MOV     DX,DI
        POP     AX
        MOV     AH,DRVCHAR
        STOSW
        MOV     AL,[DIRCHAR]
        STOSB
        JMP     ZPRINT

$EXIT:
        PUSH    ES
        MOV     ES,[RESSEG]
ASSUME  ES:RESGROUP
        MOV     AX,[PARENT]
        MOV     WORD PTR ES:[PDB_Parent_PID],AX

IF IBM
        CMP     [PERMCOM],0
        JNZ     NORESETVEC      ;Don't reset the vector if a PERMCOM
        LDS     DX,DWORD PTR ES:[SYS_CALL]
ASSUME  DS:NOTHING
        MOV     AX,(SET_INTERRUPT_VECTOR SHL 8) + INT_COMMAND
        INT     int_command
NORESETVEC:
ENDIF

        POP     ES
ASSUME  ES:TRANGROUP
        MOV     ES,[TPA]
        MOV     AH,DEALLOC
        INT     int_command                             ; Now running in "free" space
        MOV     AX,(EXIT SHL 8)
        INT     int_command

CTTY:
        CALL    SETPATH         ; Get spec
        MOV     AX,(OPEN SHL 8) OR 2    ; Read and write
        INT     int_command             ; Open new device
        JC      ISBADDEV
        MOV     BX,AX
        MOV     AX,IOCTL SHL 8
        INT     int_command
        TEST    DL,80H
        JNZ     DEVISOK
        MOV     AH,CLOSE       ; Close initial handle
        INT     int_command
ISBADDEV:
        MOV     DX,OFFSET TRANGROUP:BADDEV
        CALL    PRINT
        JMP     RESRET

DEVISOK:
        XOR     DH,DH
        OR      DL,3            ; Make sure has CON attributes
        MOV     AX,(IOCTL SHL 8) OR 1
        INT     int_command
        PUSH    BX                      ; Save handle
        MOV     CX,3
        XOR     BX,BX
ICLLOOP:                                ; Close basic handles
        MOV     AH,CLOSE
        INT     int_command
        INC     BX
        LOOP    ICLLOOP
        POP     BX              ; Get handle
        MOV     AH,XDUP
        INT     int_command             ; Dup it to 0
        MOV     AH,XDUP
        INT     int_command             ; Dup to 1
        MOV     AH,XDUP
        INT     int_command             ; Dup to 2
        MOV     AH,CLOSE        ; Close initial handle
        INT     int_command
RESRET:
        MOV     DS,[RESSEG]
ASSUME  DS:RESGROUP
        PUSH    DS
        MOV     AX,WORD PTR DS:[PDB_JFN_Table]           ; Get new 0 and 1
        MOV     [IO_SAVE],AX
        MOV     AX,OFFSET RESGROUP:LODCOM1
        PUSH    AX
ZMMMM   PROC FAR
        RET                     ; Force header to be checked
ZMMMM   ENDP

TRANCODE        ENDS
        END