Subversion Repositories SvarDOS

Rev

Rev 463 | Rev 490 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
349 mateuszvis 1
;
2
; rmod - resident module of the SvarCOM command interpreter
3
;
4
; Copyright (C) 2021 Mateusz Viste
5
; MIT license
6
;
7
; this is installed in memory by the transient part of SvarCOM. it has only
8
; two jobs: providing a resident buffer for command history, environment, etc
9
; and respawning COMMAND.COM whenever necessary.
10
 
11
CPU 8086
459 mateuszvis 12
org 0x100
349 mateuszvis 13
 
459 mateuszvis 14
PSP_ENVSEG equ 0x2C
15
 
349 mateuszvis 16
section .text    ; all goes into code segment
17
 
350 mateuszvis 18
                 ; offset
19
SIG1 dw 0x1983   ;  +0
20
SIG2 dw 0x1985   ;  +2
21
SIG3 dw 0x2017   ;  +4
22
SIG4 dw 0x2019   ;  +6
349 mateuszvis 23
 
461 mateuszvis 24
FFU_UNUSED dw 0  ;  +8
349 mateuszvis 25
 
353 mateuszvis 26
; exit code of last application
27
LEXCODE  dw 0    ; +0Ah
28
 
366 mateuszvis 29
; offset of the COMSPEC variable in the environment block, 0 means "use
30
; boot drive". this value is patched by the transient part of COMMAND.COM
450 mateuszvis 31
COMSPECPTR dw 0  ; +0Ch
349 mateuszvis 32
 
366 mateuszvis 33
; fallback COMSPEC string used if no COMPSEC is present in the environment
34
; drive. drive is patched by the transient part of COMMAND.COM
450 mateuszvis 35
COMSPECBOOT db "@:\COMMAND.COM", 0 ; +0Eh
350 mateuszvis 36
 
460 mateuszvis 37
; ExecParamRec used by INT 21h, AX=4b00 (load and execute program), 14 bytes:
38
;  offset  size  content
39
;     +0     2   segment of environment for child (0 = current)
40
;     +2     4   address of command line to place at PSP:0080
41
;     +6     4   address of an FCB to be placed at PSP:005c
42
;    +0Ah    4   address of an FCB to be placed at PSP:006c
43
EXEC_PARAM_REC db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   ; +1Dh
366 mateuszvis 44
 
461 mateuszvis 45
; Program to execute, preset by SvarCOM (128 bytes, ASCIIZ)  ; +2Bh
46
EXECPROG dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
460 mateuszvis 47
 
461 mateuszvis 48
skipsig:         ; +ABh
49
 
349 mateuszvis 50
; set up CS=DS=SS and point SP to my private stack buffer
51
mov ax, cs
52
mov ds, ax
53
mov es, ax
54
mov ss, ax
55
mov sp, STACKPTR
56
 
460 mateuszvis 57
; should I executed command.com or a pre-set application?
58
or [EXECPROG], byte 0
59
jz EXEC_COMMAND_COM
60
 
461 mateuszvis 61
; TODO: perhaps I should call the DOS SetPSP function here? But if I do, the
62
;       int 21h, ah=50h call freezes...
63
;mov ah, 0x50           ; DOS 2+ -- Set PSP
64
;mov bx, cs
65
;int 0x21
460 mateuszvis 66
 
67
; exec an application preset (by SvarCOM) in the ExecParamRec
68
mov ax, 0x4B00         ; DOS 2+ - load & execute program
461 mateuszvis 69
mov dx, EXECPROG       ; DS:DX  - ASCIZ program name (preset at PSP[already)
460 mateuszvis 70
mov bx, EXEC_PARAM_REC ; ES:BX  - parameter block pointer
71
int 0x21
465 mateuszvis 72
mov [cs:EXECPROG], byte 0 ; do not run app again (+DS might have been changed)
460 mateuszvis 73
 
463 mateuszvis 74
jmp short skipsig      ; enforce valid ds/ss/etc (can be lost after int 21,4b)
75
 
460 mateuszvis 76
EXEC_COMMAND_COM:
77
 
353 mateuszvis 78
; collect the exit code of previous application
79
mov ah, 0x4D
80
int 0x21
81
xor ah, ah          ; clear out termination status, I only want the exit code
82
mov [LEXCODE], ax
83
 
460 mateuszvis 84
; zero out the exec param block (14 bytes)
85
mov al, 0              ; byte to write
86
mov cx, 14             ; how many times
87
mov di, EXEC_PARAM_REC ; ES:DI = destination
88
cld                    ; stosb must move forward
89
rep stosb              ; repeat cx times
90
 
366 mateuszvis 91
; preset the default COMSPEC pointer to ES:DX (ES is already set to DS)
92
mov dx, COMSPECBOOT
93
 
94
; do I have a valid COMSPEC?
95
or [COMSPECPTR], word 0
96
jz USEDEFAULTCOMSPEC
459 mateuszvis 97
; set ES:DX to actual COMSPEC (in env segment)
98
mov es, [PSP_ENVSEG]
366 mateuszvis 99
mov dx, [COMSPECPTR]
100
USEDEFAULTCOMSPEC:
101
 
349 mateuszvis 102
; prepare the exec param block
459 mateuszvis 103
mov ax, [PSP_ENVSEG]
350 mateuszvis 104
mov [EXEC_PARAM_REC], ax
465 mateuszvis 105
mov [EXEC_PARAM_REC+2], word CMDTAIL
442 mateuszvis 106
mov [EXEC_PARAM_REC+4], cs
349 mateuszvis 107
 
108
; execute command.com
109
mov ax, 0x4B00         ; DOS 2+ - load & execute program
366 mateuszvis 110
push es                ;
111
pop ds                 ;
112
;mov dx, COMSPEC       ; DS:DX  - ASCIZ program name (preset already)
113
push cs
114
pop es
349 mateuszvis 115
mov bx, EXEC_PARAM_REC ; ES:BX  - parameter block pointer
116
int 0x21
117
 
118
; if all went well, jump back to start
119
jnc skipsig
120
 
366 mateuszvis 121
; restore DS=CS
122
mov bx, cs
123
mov ds, bx
124
 
349 mateuszvis 125
; update error string so it contains the error number
126
add al, '0'
127
mov [ERRLOAD + 4], al
128
 
366 mateuszvis 129
; display error message
349 mateuszvis 130
mov ah, 0x09
131
mov dx, ERRLOAD
132
int 0x21
133
 
134
; wait for keypress
135
mov ah, 0x08
136
int 0x21
137
 
138
; back to program start
139
jmp skipsig
140
 
460 mateuszvis 141
; command.com tail arguments, in PSP format: length byte followed by args and
465 mateuszvis 142
; terminated with \r) - a single 0x0A byte is passed so SvarCOM knows it is
143
; called as respawn (as opposed to being invoked as a normal application)
144
; this allows multiple copies of SvarCOM to stack upon each other.
145
CMDTAIL db 0x01, 0x0A, 0x0D
442 mateuszvis 146
 
366 mateuszvis 147
ERRLOAD db "ERR x, FAILED TO LOAD COMMAND.COM", 13, 10, '$'
349 mateuszvis 148
 
366 mateuszvis 149
; DOS int 21h functions that I use require at least 32 bytes of stack, here I
150
; allocate 64 bytes to be sure
349 mateuszvis 151
STACKBUF db "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"
152
STACKPTR db "xx"