; From andrew kennedy <andrew-kennedy@hlp.com>
; colshell.asm  This changes the prompt before SHELLING out, and restores
;               it to $p$g on return
;
;   This version has colors in the prompt.
;
;

.MODEL SMALL
.STACK       200h

.DATA

cmd          db           lcmd_lin-1
cmd_lin      db           'PROMPT=SHELL Type $e[0m$e[31;40;5mEXIT $e[0m$e[37;40;1mto return.$_$p$g',0dh
lcmd_lin     equ          $-cmd_lin

cmd1         db           len-1
com          db           'command',0dh
len          equ          $-com

cmd2          db          lin-1
pro           db          'PROMPT=$p$g',0dh ; restore prompt
lin           equ         $-pro

msg1         db           'Preparing to SHELL out.',10,13,'Press any key.',10,13,'(S)hell out',10,13,'$'

msg2         db           10,13,'Returning to program.',10,13,'$'

old_sp       dw           ?
old_ss       dw           ?

.code

start:       mov          ax,@data
        mov          ds,ax

        mov          ah,0                   ; clear screen
        mov          al,3
        int          10h

        lea          dx,msg1
        mov          ah,09h
        int          21h
check:
        mov          ah,10h
        int          16h
        cmp          al,'s'
        jz           short next
        jmp          check
next:
        mov          bx,seg end_seg         ; Get end of our program
        mov          ax,es                  ; ES is seg of PSP
        sub          bx,ax                  ; BX = memory to keep
        mov          ah,4ah                 ; Set memory block
        int          21h
        jc           exit                   ; Go if error

; set prompt for shell

        push         ds                     ; Save DS
        mov          cs:old_sp,sp           ; Save our stack
        mov          cs:old_ss,ss

        lea          si,cmd                 ; DS:SI ==> command
        int          2eh                    ; Execute command

        cli                                 ; Turn off interrupts
        mov          sp,cs:old_sp           ; Restore stack
        mov          ss,cs:old_ss
        sti                                 ; Interrupts back on
        pop          ds                     ; Restore saved registers
 ; SHELL out
        push         ds
        mov          cs:old_sp,sp
        mov          cs:old_ss,ss
        lea          si,cmd1
        int          2eh
        cli
        mov          sp,cs:old_sp
        mov          ss,cs:old_ss
        sti
        pop          ds

; restore prompt to $p$g

        push         ds
        mov          cs:old_sp,sp
        mov          cs:old_ss,ss
        lea          si,cmd2
        int          2eh
        cli
        mov          sp,cs:old_sp
        mov          ss,cs:old_ss
        sti
        pop          ds
        lea          dx,msg2
        mov          ah,9
        int          21h
exit:
        mov          ax,4c00h
        int          21h

end_seg      segment
end_seg      ends

end          start

