forked from MirrorRepos/RomWBW
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
444 lines
23 KiB
444 lines
23 KiB
|
|
.cs 5
|
|
.mt 5
|
|
.mb 6
|
|
.pl 66
|
|
.ll 65
|
|
.po 10
|
|
.hm 2
|
|
.fm 2
|
|
.he
|
|
.bp
|
|
.tc 5.3 A Sample File-to-File Copy Program
|
|
.he CP/M Operating System Manual 5.3 A Sample Copy Program
|
|
.sh
|
|
5.3 A Sample File-to-File Copy Program
|
|
.qs
|
|
.pp
|
|
The following program provides a relatively simple example of file
|
|
operations. The program source file is created as COPY.ASM using
|
|
the CP/M ED program and then assembled using ASM or MAC, resulting
|
|
in a HEX file. The LOAD program is used to produce a COPY.COM
|
|
file that executes directly under the CCP. The program begins
|
|
by setting the stack pointer to a local area and proceeds to move
|
|
the second name from the default area at 006CH to a 33-byte File
|
|
Control Block called DFCB. The DFCB is then prepared for file
|
|
operations by clearing the current record field. At this point,
|
|
the source and destination FCBs are ready for processing, because
|
|
the SFCB at 005CH is properly set up by the CCP upon entry to the
|
|
COPY program. That is, the first name is placed into the default
|
|
FCB, with the proper fields zeroed, including the current record
|
|
field at 007CH. The program continues by opening the source
|
|
file, deleting any existing destination file, and creating the destination
|
|
file. If all this is successful, the program loops at the label
|
|
COPY until each record is read from the source file and placed into the
|
|
destination file. Upon completion of the data transfer, the
|
|
destination file is closed and the program returns to the
|
|
CCP command level by jumping to BOOT.
|
|
.ll 75
|
|
.sp 3
|
|
.nf
|
|
; sample file-to-file copy program
|
|
;
|
|
; at the ccp level, the command
|
|
;
|
|
; copy a:x.y b:u.v
|
|
;
|
|
; copies the file named x.y from drive
|
|
; a to a file named u.v. on drive b.
|
|
;
|
|
0000 = boot equ 0000h ;system reboot
|
|
0005 = bdos equ 0005h ;bdos entry point
|
|
005c = fcbl equ 005ch ;first file name
|
|
005c = sfcb equ fcbl ;source fcb
|
|
006c = fcb2 equ 006ch ;second file name
|
|
0080 = dbuff equ 0080h ;default buffer
|
|
0100 = tpa equ 0100h ;beginning of tpa
|
|
;
|
|
0009 = printf equ 9 ;print buffer func#
|
|
000f = openf equ 15 ;open file func#
|
|
0010 = closef equ 16 ;close file func#
|
|
0013 = deletef equ 19 ;delete file func#
|
|
0014 = readf equ 20 ;sequential read
|
|
0015 = writef equ 21 ;sequential write
|
|
0016 = makef equ 22 ;make file func#
|
|
;
|
|
0100 org tpa ;beginning of tpa
|
|
0100 311b02 lxi sp,stack ;local stack
|
|
;
|
|
; move second file name to dfcb
|
|
0103 0e10 mvi c,16 ;half an fcb
|
|
0105 116c00 lxi d,fcb2 ;source of move
|
|
0108 21da01 lxi h,dfcb ;destination fcb
|
|
010b 1a mfcb: Idax d ;source fcb
|
|
010c 13 inx d ;ready next
|
|
010d 77 mov m,a ;dest fcb
|
|
010e 23 inx h ;ready next
|
|
010f 0d dcr c ;count 16...0
|
|
0110 c10b01 jnz mfcb ;loop 16 times
|
|
;
|
|
; name has been removed, zero cr
|
|
0113 af xra a ;a = 00h
|
|
0114 32fa01 sta dfcbcr ;current rec = 0
|
|
;
|
|
; source and destination fcb's ready
|
|
;
|
|
0117 115c00 lxi d,sfcb ;source file
|
|
011a cd6901 call open ;error if 255
|
|
011d 118701 lxi d,nofile ;ready message
|
|
0120 3c inr a ;255 becomes 0
|
|
0121 cc6101 cz finis ;done if no file
|
|
;
|
|
; source file open, prep destination
|
|
0124 11da01 lxi d,dfcb ;destination
|
|
0127 cd7301 call delete ;remove if present
|
|
;
|
|
012a 11da01 lxi d,dfcb ;destination
|
|
012d cd8201 call make ;create the file
|
|
0130 119601 lxi d,nodir ;ready message
|
|
0133 3c inr a ;255 becomes 0
|
|
0134 cc6101 cz finis ;done if no dir space
|
|
;
|
|
; source file open, dest file open
|
|
; copy until end of file on source
|
|
;
|
|
0137 115c00 copy: lxi d,sfcb ;source
|
|
013a cd7801 call read ;read next record
|
|
013d b7 ora a ;end of file?
|
|
013e c25101 jnz eofile ;skip write if so
|
|
;
|
|
; not end of file, write the record
|
|
0141 11da01 lix d,dfcb ;destination
|
|
0144 cd7d01 call write ;write record
|
|
0147 11a901 lxi d,space ;ready message
|
|
014a b7 ora a ;00 if write ok
|
|
014b c46101 cnz finis ;end if so
|
|
014e c33701 jmp copy ;loop until eof
|
|
;
|
|
eofile: ;end of file, close destination
|
|
0151 11da01 lxi d,dfcb ;destination
|
|
0154 cd6e01 call close ;255 if error
|
|
0157 21bb01 lxi h,wrprot ;ready message
|
|
015a 3c inr a ;255 becomes 00
|
|
015b cc6101 cz finis ;shouldn't happen
|
|
;
|
|
; copy operation complete, end
|
|
015e 11cc01 lxi d,normal ;ready message
|
|
;
|
|
finis ;write message given by de, reboot
|
|
0161 0e09 mvi c,printf
|
|
0163 cd0500 call bdos ;write message
|
|
0166 c30000 jmp boot ;reboot system
|
|
;
|
|
; system interface subroutines
|
|
; (all return directly from bdos)
|
|
;
|
|
0169 0e0f open: mvi c,openf
|
|
016b c30500 jmp bdos
|
|
;
|
|
016e 0e10 close: mvi c,closef
|
|
0170 c30500 jmp bdos
|
|
;
|
|
0173 0e13 delete mvi c,deletef
|
|
0175 c30500 jmp bdos
|
|
;
|
|
0178 0e14 read: mvi c,readf
|
|
017a c30500 jmp bdos
|
|
;
|
|
017d 0e15 write: mvi c,writef
|
|
017f c30500 jmp bdos
|
|
;
|
|
0182 0e16 make: mvi c,makef
|
|
0184 c30500 jmp bdos
|
|
;
|
|
; console messages
|
|
0187 6e6f20f nofile: db 'no source file$'
|
|
0196 6e6f209 nodir: db 'no directory space$'
|
|
01a9 6f7574f space: db 'out of dat space$'
|
|
01bb 7772695 wrprot: db 'write protected?$'
|
|
01cc 636f700 normal: db 'copy complete$'
|
|
;
|
|
; data areas
|
|
01da dfcb: ds 33 ;destination fcb
|
|
01fa dfcbcr equ dfcb+32 ;current record
|
|
;
|
|
01fb ds 32 ;16 level stack
|
|
stack:
|
|
021b end
|
|
.ll 65
|
|
.fi
|
|
.in 0
|
|
.sp 2
|
|
.pp
|
|
Note that there are several simplifications in this
|
|
particular program. First, there are no checks for invalid filenames
|
|
that could contain ambiguous references. This
|
|
situation could be detected by scanning the 32-byte default area
|
|
starting at location 005CH for ASCII question marks. A check
|
|
should also be make to ensure that the filenames have
|
|
been included (check locations 005DH and 006DH for nonblank ASCII
|
|
characters). Finally, a check should be made to ensure that the
|
|
source and destination filenames are different. An improvement
|
|
in speed could be obtained by buffering more data on each read
|
|
operation. One could, for example, determine the size of memory
|
|
by fetching FBASE from location 0006H and using the entire
|
|
remaining portion of memory for a data buffer. In this case, the
|
|
programmer simply resets the DMA address to the next successive
|
|
128-byte area before each read. Upon writing to the destination
|
|
file, the DMA address is reset to the beginning of the buffer and
|
|
incremented by 128 bytes to the end as each record is
|
|
transferred to the destination file.
|
|
.sp 2
|
|
.he CP/M Operating System Manual 5.4 A Sample File Dump Utility
|
|
.tc 5.4 A Sample File Dump Utility
|
|
.sh
|
|
5.4 A Sample File Dump Utility
|
|
.qs
|
|
.pp
|
|
The following file dump program is slightly more complex than
|
|
the simple copy program given in the previous section. The dump
|
|
program reads an input file, specified in the CCP command line,
|
|
and displays the content of each record in hexadecimal format at
|
|
the console. Note that the dump program saves the CCP's stack
|
|
upon entry, resets the stack to a local area, and restores the
|
|
CCP's stack before returning directly to the CCP. Thus, the
|
|
dump program does not perform and warm start at the end of
|
|
processing.
|
|
.ll 75
|
|
.sp 3
|
|
.nf
|
|
x.in 5
|
|
;DUMP program reads input file and displays
|
|
hex data
|
|
;
|
|
0100 org 100h
|
|
0005 = bdos equ 0005h = ;bdos entry point
|
|
0001 = cons equ 1 ;read console
|
|
0002 = typef equ 2 ;type function
|
|
0009 = printf equ 9 ;buffer print entry
|
|
000b = brkf equ 11 ;break key function
|
|
;(true if char
|
|
000f = openf equ 15 ;file open
|
|
0014 = readf equ 20 ;read function
|
|
;
|
|
005c = fcb equ 5ch ;file control block
|
|
;address
|
|
0080 = buff equ 80h ;input disk buffer
|
|
;address
|
|
;
|
|
; non graphic characters
|
|
000d = cr equ 0dh ;carriage return
|
|
000a = If equ 0ah ;line feed
|
|
;
|
|
; file control block definitions
|
|
005c = fcbdn equ fcb+0 ;disk name
|
|
005d = fcbfn equ fcb+1 ;file name
|
|
0065 = fcbft equ fcb+9 ;disk file type (3
|
|
;characters)
|
|
0068 = fcbrl equ fcb+12 ;file's current reel
|
|
;number
|
|
006b = fcbrc equ fcb+15 ;file's record count (0 to
|
|
;128)128)
|
|
007c = fcbcr' equ fcb+32 ;current (next) record
|
|
;number (0
|
|
007d = fcbin equ fcb+33 ;fcb length
|
|
;
|
|
; set up stack
|
|
0100 210000 lxi h,0
|
|
0103 39 dad sp
|
|
; entry stack pointer in hl from the ccp
|
|
0104 221502 shld oldsp
|
|
; set sp to local stack area (restored at
|
|
; finis)
|
|
0107 315702 lxi sp,stktop
|
|
; read and print successive buffers
|
|
010a cdc101 call setup ;set up input file
|
|
010d feff cpi 255 ;255 if file not present
|
|
010f c21b01 jnz openok ;skip if open is ok
|
|
;
|
|
; file not there, give error message and
|
|
; return
|
|
0112 11f301 lxi d,opnmsg
|
|
0115 cd9c01 call err
|
|
0118 c35101 jmp finis ;to return
|
|
;
|
|
openok: ;open operation ok, set buffer index to
|
|
;end
|
|
011b 3e80 mvi a,80h
|
|
011d 321302 sta ibp ;set buffer pointer to 80h
|
|
; hl contains next address to print
|
|
0120 210000 lxi h,0 ;start with 0000
|
|
;
|
|
gloop:
|
|
0123 e5 push h ;save line position
|
|
0124 cda201 call gnb
|
|
0127 e1 pop h ;recall line position
|
|
0138 da5101 jc finis ;carry set by gnb if end
|
|
;file
|
|
012b 47 mov b,a
|
|
; print hex values
|
|
; check for line fold
|
|
012c 7d
|
|
mov a,l
|
|
012d e60f ani 0fh ;check low 4 bits
|
|
012f c24401 jnz nonum
|
|
; print line number
|
|
0132 cd7201 call crlf
|
|
;
|
|
; check for break key
|
|
0135 cd5901 call break
|
|
; accum lsb = 1 if character ready
|
|
0138 0f rrc ;into carry
|
|
0139 da5101 jc finis ;don't print any more
|
|
;
|
|
013c 7c mov a,h
|
|
013d cd8f01 call phex
|
|
0140 7d mov a,l
|
|
0141 cd8f01 call phex
|
|
nonum
|
|
0144 23 inx h ;to next line number
|
|
0145 3e20 mvi a,''
|
|
0147 cd6501 call pchar
|
|
014a 78 mov a,b
|
|
014b cd8f01 call phex
|
|
014e c32301 jmp gloop
|
|
;
|
|
finis
|
|
; end of dump, return to cco
|
|
; (note that a jmp to 0000h reboots)
|
|
0151 cd7201 call crif
|
|
0154 2a1502 lhld oldsp
|
|
0157 f9 sphl
|
|
; stack pointer contains ccp's stack
|
|
; location
|
|
0158 c9 ret ;to the ccp
|
|
;
|
|
;
|
|
; subroutines
|
|
;
|
|
break: ;check break key (actually any key will
|
|
;do)
|
|
0159 e5d5c5 push h! push d! push b; environment
|
|
;saved
|
|
015c 0e0b mvi c,brkf
|
|
015e cd0500 call bdos
|
|
0161 c1d1e1 pop b! pop d! pop h; environment
|
|
restored
|
|
0164 c9 ret
|
|
;
|
|
pchar: ;print a character
|
|
0165 e5d5c5 push h! push d! push b; saved
|
|
0168 0e02 mvi c, typef
|
|
016a 5f mov e,a
|
|
016b cd0500 call bdos
|
|
016e c1d1e1 pop b! pop d! pop h; restored
|
|
0171 c9 ret
|
|
;
|
|
crlf
|
|
0172 3e0d mvi a,cr
|
|
0174 cd6501 call pchar
|
|
0177 3e0a mvi a,lf
|
|
0179 cd6501 call pchar
|
|
017c c9 ret
|
|
;
|
|
;
|
|
pnib: ;print nibble in reg a
|
|
017d e60f ani ofh ;low 4 bits
|
|
017f fe0a cpi 10
|
|
0181 d28901 jnc p10
|
|
; less than or equal to 9
|
|
0184 c630 adi '0'
|
|
0186 c38b01 jmp prn
|
|
;
|
|
; greater or equal to 10
|
|
0189 c637 p10: adi 'a' - 10
|
|
018b cd6501 prn: call pchar
|
|
018e c9 ret
|
|
;
|
|
phex ;print hex char in reg a
|
|
018f f5 pushpsw
|
|
0190 0f rrc
|
|
0191 0f rrc
|
|
0192 0f rrc
|
|
0193 0f rrc
|
|
0194 cd7d01 call pnib ;print nibble
|
|
0197 f1 pop psw
|
|
0198 cd7d01 call pnip
|
|
019b c9 ret
|
|
;
|
|
err: ;print error message
|
|
; d,e addresses message ending with "$"
|
|
019c 0e09 mvi c,printf ;print buffer
|
|
;function
|
|
019e cd0500 call bdos
|
|
01a1 c9 ret
|
|
;
|
|
;
|
|
gnb: ;get next byte
|
|
01a2 3a1302 lda ibp
|
|
01a5 fe80 cpi 80h
|
|
01a7 c2b301 jnz g0
|
|
; read another buffer
|
|
;
|
|
;
|
|
01aa cdce01 call diskr
|
|
01ad b7 ora a ;zero value if read ok
|
|
01ae cab301 jz g0 ;for another byte
|
|
; end of data, return with carry set for eof
|
|
01b1 37 stc
|
|
01b2 c9 ret
|
|
;
|
|
g0: ;read the byte at buff+reg a
|
|
01b3 5f mov e,a ;Is byte of buffer index
|
|
01b4 1600 mvi d,0 ;double precision
|
|
;index to de
|
|
01b6 3c inr a ;index=index+1
|
|
01b7 321302 sta ibp ;back to memory
|
|
; pointer is incremented
|
|
; save the current file address
|
|
01ba 218000 lxi h,buff
|
|
01bd 19 dad d
|
|
; absolute character address is in hl
|
|
01be 7e mov a,m
|
|
; byte is in the accumulator
|
|
01bf b7 ora a ;reset carry bit
|
|
01c0 c9 ret
|
|
;
|
|
setup: ;set up file
|
|
; open the file for input
|
|
01c1 af xra a ;zero to accum
|
|
01c2 327c00 sta fcbcr ;clear current record
|
|
;
|
|
01c5 115c00 lxi d,fcb
|
|
01c8 0e0f mvi c,openf
|
|
01ca cd0500 call bdos
|
|
; 255 in accum if open error
|
|
01cd c9 ret
|
|
;
|
|
diskr: ;read disk file record
|
|
01ce e5d5c5 push h! push d! push b
|
|
01d1 115c00 lxi d,fcb
|
|
01d4 0e14 mvi c,readf
|
|
01d6 cd0500 call bdos
|
|
01d9 c1d1e1 pop b! pop d! pop h
|
|
01dc c9 ret
|
|
;
|
|
; fixed message area
|
|
01dd 46494c0 signon: db 'file dump version 2.0$'
|
|
01f3 0d0a4e0 opnmsg: db cr,lf,'no input file present on
|
|
disk$'
|
|
|
|
; variable area
|
|
0213 ibp: ds 2 ;input buffer pointer
|
|
0215 oldsp: ds 2 ;entry sp value from ccp
|
|
;
|
|
; stack area
|
|
0217 ; ds 64 ;reserve 32 level stack
|
|
stktop:
|
|
;
|
|
0257 end
|
|
.ll 65
|
|
.fi
|
|
.in 0
|
|
.nx fived
|
|
|