Subversion Repositories SvarDOS

Rev

Rev 459 | Rev 461 | 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
 
460 mateuszvis 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
26
; stores the command to be executed somewhere within rmod's segment.
27
EXECPROG dw 0    ;  +8
349 mateuszvis 28
 
353 mateuszvis 29
; exit code of last application
30
LEXCODE  dw 0    ; +0Ah
31
 
366 mateuszvis 32
; offset of the COMSPEC variable in the environment block, 0 means "use
33
; boot drive". this value is patched by the transient part of COMMAND.COM
450 mateuszvis 34
COMSPECPTR dw 0  ; +0Ch
349 mateuszvis 35
 
366 mateuszvis 36
; fallback COMSPEC string used if no COMPSEC is present in the environment
37
; drive. drive is patched by the transient part of COMMAND.COM
450 mateuszvis 38
COMSPECBOOT db "@:\COMMAND.COM", 0 ; +0Eh
350 mateuszvis 39
 
460 mateuszvis 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
366 mateuszvis 47
 
460 mateuszvis 48
skipsig:         ; +2Bh
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
 
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
 
353 mateuszvis 72
; collect the exit code of previous application
73
mov ah, 0x4D
74
int 0x21
75
xor ah, ah          ; clear out termination status, I only want the exit code
76
mov [LEXCODE], ax
77
 
460 mateuszvis 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
 
366 mateuszvis 85
; preset the default COMSPEC pointer to ES:DX (ES is already set to DS)
86
mov dx, COMSPECBOOT
87
 
88
; do I have a valid COMSPEC?
89
or [COMSPECPTR], word 0
90
jz USEDEFAULTCOMSPEC
459 mateuszvis 91
; set ES:DX to actual COMSPEC (in env segment)
92
mov es, [PSP_ENVSEG]
366 mateuszvis 93
mov dx, [COMSPECPTR]
94
USEDEFAULTCOMSPEC:
95
 
349 mateuszvis 96
; prepare the exec param block
459 mateuszvis 97
mov ax, [PSP_ENVSEG]
350 mateuszvis 98
mov [EXEC_PARAM_REC], ax
442 mateuszvis 99
mov ax, CMDTAIL
100
mov [EXEC_PARAM_REC+2], ax
101
mov [EXEC_PARAM_REC+4], cs
349 mateuszvis 102
 
103
; execute command.com
104
mov ax, 0x4B00         ; DOS 2+ - load & execute program
366 mateuszvis 105
push es                ;
106
pop ds                 ;
107
;mov dx, COMSPEC       ; DS:DX  - ASCIZ program name (preset already)
108
push cs
109
pop es
349 mateuszvis 110
mov bx, EXEC_PARAM_REC ; ES:BX  - parameter block pointer
111
int 0x21
112
 
113
; if all went well, jump back to start
114
jnc skipsig
115
 
366 mateuszvis 116
; restore DS=CS
117
mov bx, cs
118
mov ds, bx
119
 
349 mateuszvis 120
; update error string so it contains the error number
121
add al, '0'
122
mov [ERRLOAD + 4], al
123
 
366 mateuszvis 124
; display error message
349 mateuszvis 125
mov ah, 0x09
126
mov dx, ERRLOAD
127
int 0x21
128
 
129
; wait for keypress
130
mov ah, 0x08
131
int 0x21
132
 
133
; back to program start
134
jmp skipsig
135
 
460 mateuszvis 136
; command.com tail arguments, in PSP format: length byte followed by args and
137
; terminated with \r)
138
CMDTAIL db 0x00, 0x0D
442 mateuszvis 139
 
366 mateuszvis 140
ERRLOAD db "ERR x, FAILED TO LOAD COMMAND.COM", 13, 10, '$'
349 mateuszvis 141
 
366 mateuszvis 142
; DOS int 21h functions that I use require at least 32 bytes of stack, here I
143
; allocate 64 bytes to be sure
349 mateuszvis 144
STACKBUF db "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"
145
STACKPTR db "xx"