;******************************************************* ; ; TCOPY - Example program to write the system tracks ; for a Concurrent CP/M Boot Disk on a ; CompuPro Computer System. ; ;******************************************************* ; This program is used to read a binary image file ; which will be loaded on the disk boot tracks. This ; binary image is used to bootstrap the Concurrent CP/M ; system file. The binary image file which TCOPY reads ; has no CMD header and must be fit within the size of ; the boot tracks we are going to write. ; This program is intended to serve as an example ; to be modified by the OEM for differently sized loaders, ; and differently sized system track(s). ; Note: TCOPY must be run under CP/M-86 1.1 and not under ; Concurrent CP/M since TCOPY performs direct BIOS calls to ; write to the disk. ; The following commands are used to generate TCOPY.CMD ; RASM86 TCOPY ; LINK86 TCOPY ; ;******************************************************* title 'TCOPY - Copy Track 0' ; CP/M-86 function names ; console functions c_read equ 1 c_writebuf equ 9 ; file functions f_open equ 15 f_readrand equ 33 f_setdma equ 26 f_setdmaseg equ 51 ; drive functions drv_get equ 25 dph_dpb equ 10 dpb_spt equ 0 dpb_off equ 13 ; system functions s_termcpm equ 0 s_bdosver equ 12 s_dirbios equ 50 bdos_version equ 0022h ; direct Bios Parameter Block bpb_func equ byte ptr 0 bpb_cx equ word ptr 1 bpb_dx equ word ptr 3 ; ASCII linefeed and carriage return lf equ 10 cr equ 13 ;------------------------------------------------------- CSEG org 0000h ;use CCP stack mov cl,c_writebuf ;display sign on message mov dx,offset sign_on_msg int 224 mov cl,s_bdosver int 224 cmp ax,bdos_version! je version_ok mov dx,offset version_msg jmp error version_ok: mov cl,drv_get ;get default drive number int 224 mov default_drive,al add al,'A' mov dest_drive,al ;set drive letter in message mov cl,f_open ;open the file given as mov dx,offset fcb ;the 1st command parameter, int 224 ;it is put at 05CH by cmp al,0ffh! jne file_ok ;the program load mov dx,offset open_msg jmp error file_ok: mov current_dma,offset image_buffer mov r0,0 ;start with sector 0, assume mov cx,buf_siz/128 ;no CMD header in the file file_read: push cx mov cl,f_setdma mov dx,current_dma int 224 mov cl,f_readrand ;user r0,r1,r2 for random mov dx,offset fcb ;reads int 224 pop cx test al,al! jz read_ok cmp al,1! je track_write mov dx,offset read_msg jmp error read_ok: add current_dma,128 ;set the DMA for the next sector inc r0 ;add one to the random record field loop file_read mov dx,offset length_msg ;file is larger than the number jmp error ; of available sectors to write ; We have the binary image in RAM ; Ask for destination diskette track_write: inc r0 ;r0 = number of sectors read next_diskette: mov cl,c_writebuf mov dx,offset new_disk_msg int 224 mov cl,c_read ;wait for a keystroke int 224 cmp al,3! jne not_ctrlC ;check for control C jmp done not_ctrlC: ; Using CP/M-86 function 50, Direct bios call, ; write the track image in IMAGE_BUFFER to ; track 0, on default drive. mov cl,default_drive call select_disk ;select default drive mov bx,es:dph_dpb[bx] ;get DPB mov ax,es:dpb_spt[bx] ;get sectors/track add ax,26 ;add in sectors for track 0 cmp ax,r0! jae size_ok ;check max # of sectors on boot tracks mov dx,offset length_msg ; file is larger than the number jmp error ; of available sectors to write size_ok: mov ax,es:dpb_off[bx] ;determine sides from OFF value cmp ax,2! je format_ok cmp ax,4! je format_ok mov dx,offset format_msg jmp error format_ok: shr al,1 mov second_track,al ;save track # for cylinder 1, head 0 xor cx,cx call set_track ;set track to 0 call set_dmaseg ;set DMA segment = DS mov current_sector,0 ;sectors are relative to 0 in BIOS mov current_dma,offset image_buffer mov cx,r0 ;number of 128 byte sectors to write next_sector: push cx ;save sector count call set_dmaoff call set_sector call write_sector add current_dma,128 ;next area of memory to write inc current_sector ;next sector number cmp current_sector,26 jb same_track mov cl,second_track ;cylinder 1, head 0 call set_track mov current_sector,0 same_track: pop cx ;restore sector count loop next_sector mov cl,c_writebuf ;does the user want to write mov dx,offset continue_msg ;to another diskette ? int 224 mov cl,c_read ;get response int 224 and al,05FH ;make upper case cmp al,'Y' jne done jmp next_diskette error: push dx call crlf pop dx mov cl,c_writebuf int 224 done: mov cx,s_termcpm mov dx,cx int 224 select_disk: mov al,9 ;BIOS function number of seldsk xor dx,dx jmps bios set_track: mov al,10 ;BIOS function number of settrk jmps bios set_dmaseg: mov al,17 ;BIOS function number of setdmab mov cx,ds ;dma segment we want to use jmps bios set_dmaoff: mov al,12 ;BIOS function number of setdma mov cx,current_dma jmps bios set_sector: mov al,11 ;BIOS function number of setsec mov cx,current_sector jmps bios write_sector: mov al,14 ;BIOS function number of write sector jmps bios ;error checking can be added here bios: mov bx,offset bpb ;fill in BIOS Paramenter Block mov bpb_func[bx],al mov bpb_cx[bx],cx mov bpb_dx[bx],dx mov cl,s_dirbios mov dx,bx int 224 ret crlf: mov dx,offset crlf_msg mov cl,c_writebuf int 224 ret ;------------------------------------------------------- DSEG org 0000h fcb equ ds:byte ptr .05Ch r0 equ ds:word ptr .07Dh r3 equ ds:byte ptr .07Fh sign_on_msg db cr,lf,'Example TCOPY for CompuPro Computer System' db cr,lf,'Writes track image file on boot tracks$' new_disk_msg db cr,lf,'Put destination diskette in drive ' dest_drive db 'A:' db cr,lf,'Strike any key when ready $' continue_msg db cr,lf,'Write another disk (Y/N) ? $' crlf_msg db cr,lf,'$' version_msg db 'Requires CP/M-86 1.1$' format_msg db 'Unrecognized disk format$' open_msg db 'Give file name containing boot ' db 'image, after TCOPY command$' read_msg db 'Error reading track image file$' length_msg db 'File is larger than the the number of boot sectors$' write_msg db 'Error writing on boot tracks$' image_buffer rb 26*128+8*8*128 ;area for both tracks buf_siz equ offset $ - offset image_buffer bpb rb 5 ;direct Bios Parameter Block current_dma dw 0 current_sector dw 0 default_drive db 0 second_track db 0 END