Subversion Repositories SvarDOS

Rev

Rev 459 | Rev 461 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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