home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
cpm
/
cpm86
/
fmacs86.ark
/
CCPMINT.A86
< prev
next >
Wrap
Text File
|
1989-02-09
|
23KB
|
827 lines
pagesize 86
title 'CCPM interface for FREEMACS'
v30 equ 0
files equ 8 ;max. number of files that can be opened
if v30
;macros for NEC V20/V30 or Intel 80186/286
codemacro SHLW parm:ew,count:db ;shift word left by
db 0c1h ;immediate count
modrm 4,parm
db count
endm
codemacro SHRW parm:ew,count:db ;shift word right by
db 0c1h ;immediate count
modrm 5,parm
db count
endm
endif
;CCPM function EQUs
c_attach equ 92h
c_detach equ 93h
drv_get equ 19h
f_close equ 10h
f_delete equ 13h
f_dmaoff equ 1Ah
f_dmaseg equ 33h
f_make equ 16h
f_multisec equ 2Ch
f_open equ 0Fh
f_parse equ 98h
f_readrand equ 21h
f_rename equ 17h
f_sfirst equ 11h
f_size equ 23h
f_snext equ 12h
f_usernum equ 20h
f_writerand equ 22h
p_cli equ 96h
p_pdadr equ 9Ch
p_priority equ 91h
t_seconds equ 9Bh
codemacro CCPM parm:db ;call CCPM
db 0b1h ! db parm ;mov cl,parm
db 0cdh ! db 0e0h ;int 0E0H
endm
data dseg word public
our_ds rs 0
pfcb rw 2 ;F_PARSE parameter block
flesize equ 48 ;length of file_list element
file_list rb files*flesize ;IO buffers and FCBs
file_list_end rs 0
;file list element structure
; +-------------------------------+
; 0 | FLAGS | USER CODE |
; +-------------------------------+
; 2 | (reserved) |
; +-------------------------------+
; 4 | RWPOINTER |
; | 4 bytes |
; +-------------------------------+
; 8 | FILELENGTH |
; | 4 bytes |
; +-------------------------------+
; 12 | CCPM |
; / File Control Block /
; | 36 bytes |
; +-------------------------------+
flags equ byte ptr 0 ;buffer flags 1 byte
usercode equ byte ptr 1 ;user code 1 byte
reserved equ byte ptr 2 ; 2 bytes
rwpointer equ word ptr 4 ;read/write pointer 4 bytes
filelength equ word ptr 8 ;file length 4 bytes
fcb equ byte ptr 12 ;File Control Block 36 bytes
fcb_f6 equ byte ptr fcb+6 ;read only open flag
fcb_r01 equ word ptr fcb+33 ;random record number
fcb_r2 equ byte ptr fcb+35
;
open_mask equ 80h
modf_mask equ 40h
ro_mask equ 20h
;
search_fle rb flesize
search_fle_fcb equ byte ptr search_fle+12
help_fle rb flesize
help_fle_fcb equ byte ptr help_fle+12
help_buffer rb 130
tod rb 5
dft_user rb 1
;
;data end
;stack sseg word
callers_bp equ word ptr 0[bp]
callers_di equ word ptr 2[bp]
callers_es equ word ptr 4[bp]
callers_si equ word ptr 6[bp]
callers_ds equ word ptr 8[bp]
callers_dx equ word ptr 10[bp]
callers_cx equ word ptr 12[bp]
callers_bx equ word ptr 14[bp]
callers_ax equ word ptr 16[bp]
handle_nbr equ callers_bx ;handle #
iob_count equ word ptr (-2)[bp] ;number of bytes to transfer
iodma_seg equ word ptr (-4)[bp] ;DMA segment
iodma_off equ word ptr (-6)[bp] ;DMA offset
iodma_adr equ dword ptr (-6)[bp]
iotrf_count equ word ptr (-8)[bp] ;transfer count
;stack ends
code cseg byte public
;*** assume cs:code,ds:data,es:data,ss:stack
public ccpm_init
ccpm_init:
push ds ! mov ds,own_ds
mov dl,0FFh ! ccpm f_usernum
inc al ! mov dft_user,al
pop ds ! ret
own_ds dw seg our_ds
pe_ret dw return
prolog: pop pe_ret
push ax ! push bx ! push cx ! push dx
push ds ! push si ! push es ! push di
push bp ! mov bp,sp
jmp pe_ret
epilog: pop pe_ret
mov sp,bp ! pop bp
pop di ! pop es ! pop si ! pop ds
pop dx ! pop cx ! pop bx ! pop ax
jmp pe_ret
public ccpm_create_file
ccpm_create_file: ;MS-DOS function 3CH
;enter with DS:DX -> ASCIIZ of file name
call prolog
mov ds,own_ds
call inithandle ;init file list element
mov bx,di ! call set_user ;set user code
lea dx,fcb[di] ;point to fcb
ccpm f_make ;call ccpm to create the file
or al,al ;test for error
jz ccpm_open_file_2 ;creation secceeded
cmp ah,8h ;test extended error
je ccpm_open_file_1 ;file exists already -- try to open
jmp err_return ;error
public ccpm_open_file
ccpm_open_file: ;MS-DOS function 3DH
;enter with DS:DX -> ASCIIZ of file name
call prolog
mov ds,own_ds
call inithandle ;init file list element
mov bx,di ! call set_user
ccpm_open_file_1:
lea dx,fcb[di]
ccpm f_close ;perhaps we reopen
lea dx,fcb[di]
ccpm f_open ;try to open the file
inc al ! jnz ccpm_open_file_2
jmp err_return ;file opening did not succeeded
ccpm_open_file_2:
mov bx,di ! call file_size_1 ;determine the file size
or flags[bx],open_mask ;set file open flag
mov callers_ax,bx ;return file handle in AX
jmp return
public ccpm_close_file
ccpm_close_file: ;MS-DOS function 3EH
;enter with BX = File handle number
call prolog
call check_handle
mov ds,own_ds
mov di,bx ! call set_user
test flags[di],modf_mask ;test if file has been modified
jz ccpm_close_file_1 ;jump if not
mov ax,filelength[di]
test al,7fh ;is there a partial last record
jz ccpm_close_file_1 ;jump if not
mov rwpointer[di],ax
mov ax,filelength+2[di]
mov rwpointer+2[di],ax
mov dx,offset help_buffer
mov al,1 ! call set_dma
call rw_to_recptr
lea dx,fcb[di] ;read last record
ccpm f_readrand ! mov bx,di
mov di,rwpointer[bx] ! and di,7fh ;offset to EOF
mov cx,80h ! sub cx,di ;no. of bytes till EOR
add di,offset help_buffer
push ds ! pop es
mov al,1ah ! rep stosb ;pad with EOF chars (^Z)
lea dx,fcb[bx] ! mov di,bx
ccpm f_writerand ;rewrite last record
ccpm_close_file_1:
lea dx,fcb[di]
ccpm f_close ;close the file
inc al ! jnz $+5
jmp err_return
mov flags[di],0
jmp return
set_user: ;set user number
mov dl,usercode[bx]
or dl,dl ! jnz $+6
mov dl,dft_user ! dec dl
push bx ! ccpm f_usernum
pop bx ! ret
inithandle:
mov cx,files ;number of file list elements
mov bx,offset file_list
inithandle_1: ;look for an empty file handle entry
cmp flags[bx],0
jz inithandle_2 ;element found
add bx,flesize
loop inithandle_1
jmp err_return ;no element found -- return carry
;
inithandle_2: ;entry found -- clear it
push ds ! pop es
xor ax,ax ! mov cx,flesize/2 ;clear file list element
mov di,bx ! rep stosw
push ds ! mov ds,callers_ds
mov si,callers_dx
mov di,offset help_buffer
mov cx,128 ! lodsb ! stosb ;copy ASCIIZ filename to help buffer
or al,al ! loopne $-4
pop ds ! jcxz err_return ;error -- no ASCIIZ filename
;
mov pfcb,offset help_buffer
push bx ! lea ax,fcb[bx] ;parse the file name
mov pfcb+2,ax
mov dx,offset pfcb
ccpm f_parse
pop di ! inc ax
jz err_return ;error -- invalid filename
dec ax ! jz inithandle_ret
mov si,ax ! lodsb ! cmp al,'[' ;test for options
je inithandle_3 ;options follow
inithandle_ret:
ret
inithandle_3:
lodsb ! or al,al ! jz err_return ;End of string
cmp al,']' ! je inithandle_ret ;End of options
and al,5Fh ;option char. to uppercase
mov bx,offset optiontab
inithandle_4:
cmp cs:byte ptr [bx],0
jz err_return ;end of table --- invalid option
cmp al,cs:[bx] ! je inithandle_5
lea bx,3[bx] ! jmps inithandle_4
inithandle_5:
call cs:word ptr 1[bx] ;call option routine
jmps inithandle_3
optiontab db 'G' ! dw inithandle_uc ;user code
db 'R' ! dw inithandle_r ;read only
db 0
cb10 db 10
inithandle_uc: ;"G"-option -- set user code
lodsb ! cmp al,'9' ! ja err_return
cmp al,'0' ! jb err_return
and al,0Fh ! mov dl,al
lodsb ! cmp al,'5' ! ja inithandle_uc1
cmp al,'0' ! jb inithandle_uc1
and al,0Fh ! xchg al,dl
mul cs:cb10 ! add dl,al ! inc si
inithandle_uc1:
inc dl ! mov usercode[di],dl ;save user code
dec si ! ret
inithandle_r: ;"R"-Option -- read only file
or flags[di],ro_mask ! ret
err_return:
stc ! call epilog ! ret
ret_trf:mov ax,iotrf_count
mov callers_ax,ax
return: clc ! call epilog ! ret
check_handle:
cmp bx,offset file_list
jb err_return
cmp bx,offset file_list_end
jnb err_return
ret
public ccpm_write_file
ccpm_write_file: ;MS-DOS function 40H
;enter with DS:DX -> data to write
; CX = number of bytes to write
; BX = handle number
call prolog ! call check_handle
sub sp,8 ;scratch space
mov iotrf_count,0
jcxz ret_trf ;nothing to do
call calc_dma ;preset DMA address
mov ds,own_ds
push cx ! call set_user ! pop cx
mov iob_count,cx ;save # of bytes to transfer
test rwpointer[bx],7fh ;test for broken record io
jz ccpm_write_file_1 ;direct write possible
mov dx,offset help_buffer
mov al,1 ! call set_dma ;set DMA parameters to help buffer
call rw_to_recptr ;get record ptr
lea dx,fcb[bx]
ccpm f_readrand ;read record to be partially updated
mov bx,handle_nbr
mov di,rwpointer[bx] ! and di,7fh ;partial record offset
mov cx,80h ! sub cx,di
cmp iob_count,cx ! ja $+5
mov cx,iob_count ! push cx ;partial record length
add di,offset help_buffer ;point to partial record
push ds ! pop es ! push ds
lds si,iodma_adr ! rep movsb ;copy partial record
pop ds ! mov iodma_off,si
lea dx,fcb[bx] ! push bx
ccpm f_writerand ;rewrite record
or al,al ! jz $+5
jmp err_return ;error
pop bx ! pop ax ;# of bytes transfered
add iotrf_count,ax ;update transfer count
add rwpointer[bx],ax ;update R/W pointer
adc rwpointer+2[bx],0
sub iob_count,ax
mov cx,iob_count
ccpm_write_file_1:
if v30
mov ax,cx ! shrw cx,7 ;cx = sector count
else
push cx ! mov ax,cx
mov cl,7 ! shr ax,cl
mov cx,ax ! pop ax
endif
and ax,7fh ! mov iob_count,ax ;ax = rest byte count
ccpm_write_file_2:
jcxz ccpm_write_file_3
push cx ;save total sector count
cmp cx,80h ! jbe $+5
mov cx,80h ! push cx ;save max. sector count
push ds ! lds dx,iodma_adr
call calc_dma ;form DMA address
mov ds,ax ! mov al,cl
call set_dma ;set DMA parameters
pop ds
call rw_to_recptr ;form record ptr
lea dx,fcb[bx]
ccpm f_writerand ;perform IO
or al,al ! jz $+5
jmp err_return ;IO error
mov bx,handle_nbr
pop ax ! pop cx ;retrieve record counts
sub cx,ax ;update total record count
if v30
shlw ax,7 ;# of bytes transfered
else
push cx ! mov cl,7 ! shl ax,cl ! pop cx
endif
add iotrf_count,ax ;update transfer count
add rwpointer[bx],ax ;update R/W pointer
adc rwpointer+2[bx],0
add iodma_off,ax ;update DMA address
jmps ccpm_write_file_2
ccpm_write_file_3:
mov cx,iob_count ;get rest length
jcxz ccpm_write_file_4 ;all done
mov dx,offset help_buffer ; not yet -- there's a little rest
mov al,1 ! call set_dma
call rw_to_recptr ;form record pointer
lea dx,fcb[bx] ! ccpm f_readrand ;read record
push ds ! pop es ! push ds
lds dx,iodma_adr ! call calc_dma
mov si,dx ! mov ds,ax
mov di,offset help_buffer
mov cx,iob_count ! rep movsb ;copy partial record
pop ds
mov bx,handle_nbr
lea dx,fcb[bx] ! ccpm f_writerand ;rewrite record
or ax,ax ! jz $+5
jmp err_return ;error
mov ax,iob_count ;# if bytes written
mov bx,handle_nbr
add rwpointer[bx],ax ;update R/W pointer
adc rwpointer+2[bx],0
add iotrf_count,ax
ccpm_write_file_4:
or flags[bx],modf_mask ;signal that file has been modified
mov dx,rwpointer+2[bx]
cmp dx,filelength+2[bx] ;has file been extended ?
jb ret_trf1
mov ax,rwpointer[bx]
cmp ax,filelength[bx]
jbe ret_trf1
mov filelength[bx],ax ;yes -- update file length
mov filelength+2[bx],dx
ret_trf1:
jmp ret_trf
public ccpm_read_file
ccpm_read_file: ;MS-DOS function 3FH
;enter with DS:DX -> buffer to read into
; CX = number of bytes to read
; BX = handle number
call prolog ! call check_handle
sub sp,8 ;scratch space
mov iotrf_count,0
jcxz ret_trf1 ;nothing to do
call calc_dma ;preset DMA address
mov ds,own_ds
push cx ! call set_user ! pop cx
mov ax,rwpointer[bx]
mov dx,rwpointer+2[bx]
add ax,cx ! adc dx,0
cmp dx,filelength+2[bx] ! ja $+7;shall we read past the EOF ?
cmp ax,filelength[bx] ! jbe $+9
sub ax,filelength[bx] ;yes -- truncate CX to file length
sub cx,ax ! jcxz ret_trf1 ;that's EOF
mov iob_count,cx ;save # of bytes to transfer
test rwpointer[bx],7fh ;test for broken record io
jz ccpm_read_file_1 ;direct write possible
mov dx,offset help_buffer
mov al,1 ! call set_dma ;set DMA parameters to help buffer
call rw_to_recptr ;get record ptr
lea dx,fcb[bx]
ccpm f_readrand ;read record
or al,al ! jz $+5
jmp err_return
mov bx,handle_nbr
mov si,rwpointer[bx] ! and si,7fh ;partial record offset
mov cx,80h ! sub cx,si
cmp iob_count,cx ! ja $+5
mov cx,iob_count ! push cx ;partial record length
add si,offset help_buffer ;point to partial record
les di,iodma_adr ! rep movsb ;copy partial record
mov iodma_off,di
pop ax ;# of bytes transfered
add iotrf_count,ax ;update transfer count
add rwpointer[bx],ax ;update R/W pointer
adc rwpointer+2[bx],0
sub iob_count,ax
mov cx,iob_count
;
ccpm_read_file_1:
if v30
mov ax,cx ! shrw cx,7 ;cx = sector count
else
push cx ! mov ax,cx
mov cl,7 ! shr ax,cl
mov cx,ax ! pop ax
endif
and ax,7fh ! mov iob_count,ax ;ax = rest byte count
ccpm_read_file_2:
jcxz ccpm_read_file_3
push cx ;save total sector count
cmp cx,80h ! jbe $+5
mov cx,80h ! push cx ;save max. sector count
push ds ! lds dx,iodma_adr
call calc_dma ;form DMA address
mov ds,ax ! mov al,cl
call set_dma ;set DMA parameters
pop ds
call rw_to_recptr ;form record ptr
lea dx,fcb[bx]
ccpm f_readrand ;perform IO
mov bx,handle_nbr
or al,al ! jz ccpm_read_file_2a
dec al ! jz $+5 ;EOF ?
jmp err_return ;no - IO error
shr ax,1 ! add iotrf_count,ax ;number of bytes transfered
add rwpointer[bx],ax
adc rwpointer+2[bx],0
; *** pop ax ! pop cx
jmp ret_trf2
ccpm_read_file_2a:
pop ax ! pop cx ;retrieve record counts
sub cx,ax ;update total record count
if v30
shlw ax,7 ;# of bytes transfered
else
push cx ! mov cl,7
shl ax,cl ! pop cx
endif
add iotrf_count,ax ;update transfer count
add rwpointer[bx],ax ;update R/W pointer
adc rwpointer+2[bx],0
add iodma_off,ax ;update DMA address
jmps ccpm_read_file_2
ccpm_read_file_3:
mov cx,iob_count ;get rest length
jcxz ret_trf2 ;all done
mov dx,offset help_buffer ; not yet -- there's a little rest
mov al,1 ! call set_dma
call rw_to_recptr ;form record pointer
lea dx,fcb[bx] ! ccpm f_readrand ;read record
or al,al ! jz $+5
jmp err_return
push ds ! lds dx,iodma_adr
call calc_dma ! pop ds
les di,iodma_adr
mov si,offset help_buffer
mov cx,iob_count
push cx ! rep movsb ! pop cx ;copy partial record
mov bx,handle_nbr
add rwpointer[bx],cx ;update R/W pointer
adc rwpointer+2[bx],0
add iotrf_count,cx
ret_trf2:
jmp ret_trf
calc_dma: ;recalc. DMA address
;enter with DS:DX = current DMA address
;exit with DX and IODMA_OFF = new DMA offset
; AX and IODMA_SEG = new DMA segment
mov ax,ds ! push dx
if v30
shrw dx,4 ! add ax,dx ;AX = new DMA segment
else
push cx ! mov cl,4
shr dx,cl ! pop cx ! add ax,dx
endif
mov iodma_seg,ax
pop dx ! and dx,0fh ;DX = new DMA offset
mov iodma_off,dx
ret
set_dma: ;set new DMA segment, offset, and sector count
;enter with DS = DMA segment
; DX = DMA offset
; AL = sector count
push ax ! ccpm f_dmaoff ;set DMA offset
mov dx,ds ! ccpm f_dmaseg ;set DMA segment
pop dx ! ccpm f_multisec ;set sector count
ret
rw_to_recptr: ;convert R/W pointer to record pointer
mov bx,handle_nbr
mov ax,rwpointer[bx] ;get file pointer
mov dx,rwpointer+2[bx]
mov cl,7
sar dx,1 ! rcr ax,1 ;form record pointer
loop $-4
mov fcb_r01[bx],ax ;record pointer -- low word
mov fcb_r2[bx],dl ;record pointer -- high byte
ret
public ccpm_delete_file
ccpm_delete_file: ;MS-DOS function 41H
;enter with DS:DX -> ASCIIZ filename
call prolog
mov ds,own_ds
mov bx,offset help_fle
call inithandle_2
mov bx,di ! call set_user
mov flags[di],0
lea dx,fcb[di]
ccpm f_delete
or al,al ! jz $+5
jmp err_return
jmp return
public ccpm_lseek_file
ccpm_lseek_file: ;MS-DOS function 42H
;enter with CX:DX - Distance to move
; AL - Method of moving
; BX - Handle
;exit with DX:AX - New pointer location
; >>>>> CAUTION <<<<<
;MS-DOS maintains the file length in BYTES, but CCPM in RECORDS of 128 bytes.
;Therefore, if we position to the end of a file (AL=2), we have to look in
;in last record for the last non-EOF-mark (^Z) and position after it. This
;procedure may cause TRUBBLES IN CASE OF BINARY FILES if there is an EOF-mark
;pertaining to data in the last record !!!!!
call prolog ! call check_handle
mov ds,own_ds
or al,al ! jnz ccpm_lseek_file_1
mov rwpointer[bx],dx
mov rwpointer+2[bx],cx
ccpm_lseek_file_ret:
mov callers_ax,dx
mov callers_dx,cx
jmp return
ccpm_lseek_file_1:
cmp al,1 ! jne ccpm_lseek_file_2
add dx,rwpointer[bx]
adc cx,rwpointer+2[bx]
mov rwpointer[bx],dx
mov rwpointer+2[bx],cx
jmps ccpm_lseek_file_ret
ccpm_lseek_file_err:
jmp err_return
ccpm_lseek_file_2:
cmp al,2 ! jne ccpm_lseek_file_err
call file_size
jc ccpm_lseek_file_err
mov rwpointer[bx],ax
mov rwpointer+2[bx],dx
mov callers_ax,ax
mov callers_dx,dx
jmp return
file_size:
call set_user
push bx ! lea dx,fcb[bx] ;to determine the file size correctly
ccpm f_close ! pop bx ; the file nust first be closed.
push bx ! lea dx,fcb[bx]
ccpm f_open ! pop bx
inc al ! jnz $+4 ! stc ! ret ;cannot reopen
file_size_1:
push bx ! lea dx,fcb[bx] ;compute the virt. file size
ccpm f_size ! pop bx
sub fcb_r01[bx],1 ;position to last record
sbb fcb_r2[bx],0
jnc file_size_2
xor ax,ax ! mov dx,ax ;file is empty
jmps file_size_3
file_size_2:
mov dx,offset help_buffer
push bx ! mov al,1 ;set our own DMA
call set_dma ! pop bx
push bx ! lea dx,fcb[bx] ;read the last record
ccpm f_readrand ! pop bx
mov di,offset help_buffer+127 ;point to end of our buffer
push ds ! pop es
mov cx,128 ! mov al,1ah ;and search for first non EOF char
std ! rep scasb ! cld
sub di,offset help_buffer-2 ;build buffer rel. offset
mov ax,fcb_r01[bx]
xor dx,dx ! mov dl,fcb_r2[bx]
mov cx,7 ! clc
rcl ax,1 ! rcl dx,1 ! loop $-4 ;point to first byte of last record
add ax,di ! adc dx,0 ;point to EOF mark
file_size_3:
mov filelength[bx],ax
mov filelength+2[bx],dx
ret
public ccpm_find_file
ccpm_find_file:
;enter with AH = 0 To find first entry (MS-DOS function 4EH)
; DS:DX pointer to ASCIIZ filename
; ES:DI where to put the resultant ASCIIZ filename
; AH <> 0 To find the next entry (MS-DOS function 4F)
; ES:DI where to put the resultant ASCIIZ filename
; >>>>>>> CAUTION: not MS-DOS compatible (yet) !!! <<<<<<<
call prolog
mov ds,own_ds
mov dx,offset help_buffer
mov al,1 ! call set_dma ;set DMA address
mov ax,callers_ax
or ah,ah ! jnz ccpm_find_file_1
mov bx,offset search_fle
call inithandle_2
cmp fcb[di],0 ! jne ccpm_file_0
ccpm drv_get ! inc al ! mov fcb[di],al ;set drive to default
ccpm_file_0:
mov bx,di ! call set_user
lea dx,fcb[di] ! ccpm f_sfirst ;find first entry
cmp al,0ffh ! jnz ccpm_find_file_2
jmp err_return
ccpm_find_file_1:
mov bx,offset search_fle
call set_user
mov dx,offset search_fle_fcb
ccpm f_snext ;find next entry
cmp al,0ffh ! jne ccpm_find_file_2
jmp err_return
ccpm_find_file_2: ;copy back the filename
les di,dword ptr callers_di ;load destination
if v30
xor ah,ah ! shlw ax,5 ;source offset rel. to DMA buffer
else
xor ah,ah ! mov cl,5 ! shl ax,cl
endif
mov si,ax ! lea si,help_buffer[si] ;point to DIR entry
lodsb ! and al,0fh ! push ax ;save user code from DIR
mov al,search_fle_fcb ;drive code from fcb
add al,'@' ! mov ah,':' ! stosw ;store drive specification
push si ! mov cx,8 ! lodsb ;copy file name
and al,7Fh ! cmp al,32 ! je $+5 ; blank=exit loop
stosb ! loop $-8
pop si ! lea si,8[si] ;point to extention
cmp byte ptr [si],32 ;is there an extention ?
je ccpm_find_file_3 ;jump if not
mov al,'.' ! stosb ;else append '.'
mov cx,3 ! lodsb
and al,7Fh ! cmp al,20h ;and copy file extention
je $+5 ! stosb ! loop $-8
ccpm_find_file_3: ;form user specification
mov ax,'G[' ! stosw ! pop ax ;restore user from DIR entry
aaa ! or ax,3030h ;form ASCII user number
cmp ah,30h ! je $+7
xchg al,ah ! stosb ;store high digit
xchg al,ah ! stosb ;store low digit
mov ax,']' ! stosw ;store final delimiter
jmp return
public ccpm_rename_file
ccpm_rename_file: ;MS-DOS function 56h
;enter with DS:DX - old ASCIIZ file name
; ES:DI - new ASCIIZ file name
;exit with CARRY in error
call prolog
mov ds,own_ds ! mov bx,offset help_fle
call inithandle_2
mov bx,di ! call set_user
mov es,own_ds
mov di,offset help_fle_fcb+17
mov al,' ' ! mov cx,11
rep stosb ;preset new file name with blanks
mov si,callers_di
mov ds,callers_es ;copy new file name
mov di,offset help_fle_fcb+17 ;into FCB
mov cl,9
ccpm_rename_file_1:
lodsb ! cmp al,'.'
je ccpm_rename_file_2 ;extension follow
or al,al ! jz ccpm_rename_file_4
call to_upper ! stosb
loop ccpm_rename_file_1
jmp err_return ;new file name to long
ccpm_rename_file_2:
mov di,offset help_fle_fcb+17+8
mov cl,4 ;copy new extension
ccpm_rename_file_3:
lodsb ! or al,al
jz ccpm_rename_file_4
call to_upper ! stosb
loop ccpm_rename_file_3
jmp err_return ;new extention is to long
ccpm_rename_file_4:
mov ds,own_ds
mov dx,offset help_fle_fcb
ccpm f_rename ;rename the file
inc al ! jz $+5
jmp return
jmp err_return ;error -- cannot rename the file
to_upper:
and al,7fh ;remove status bits
cmp al,'a' ! jb to_upper_exit
cmp al,'z' ! ja to_upper_exit
and al,5fh
to_upper_exit:
ret
public ccpm_get_time
ccpm_get_time: ;MS-DOS function 2CH
;exit with CH - Hour (0-23)
; CL - Minutes (0-59)
; DH - Seconds (0-59)
; DL - Hundredths (0-99) >>>>>>> currently 0 !!!! <<<<<<<
call prolog
mov ds,own_ds
mov dx,offset tod
ccpm t_seconds ;get current time and day
mov cl,4 ! xor dl,dl ;>>>>>>>> clear hundredths <<<<<<<
xor ah,ah ! mov al,tod+4 ;get seconds
shl ax,cl ! shr al,cl
aad ! mov dh,al
mov al,tod+3 ;get minutes
shl ax,cl ! shr al,cl
aad ! mov bl,al
mov al,tod+2 ;get hour
shl ax,cl ! shr al,cl
aad ! mov bh,al
mov callers_dx,dx
mov callers_cx,bx
jmp return
public ccpm_execute_program
;enter with ds:si,cx = P_CLI string
;exit with ax = Error code
ccpm_execute_program:
call prolog
mov es,own_ds
mov di,offset help_buffer
lds si,dword ptr callers_si
xor al,al ! stosb
and cx,7fh ! rep movsb
stosb ! mov ds,own_ds
ccpm p_pdadr ;get our PD address
mov al,es:byte ptr 5[bx] ;get our priority
push ax ! push es ! push bx ;save all
mov si,es:word ptr 1eh[bx] ;get parent's PD
or si,si ! jz execute_program_0 ;I'm alone
mov al,es:byte ptr 5[si] ;get parent's prio
dec al ! mov es:byte ptr 5[bx],al ;I'm one better
execute_program_0:
mov dx,offset help_buffer
ccpm p_cli
or ax,ax ! jz execute_program_1
mov ax,cx
execute_program_1:
mov callers_ax,ax
ccpm c_attach
pop bx ! pop es ! pop ax
mov es:byte ptr 5[bx],al ;reset our priority
jmp return
end