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