;****************************************************** ;* * ;* Disk Read Program * ;* Will read specified disc, side, track, sector * ;* and print in alpanumeric and hexadecimal * ;* Assumes Double density disk except for * ;* track 00 side 0 which is single density * ;* Written by Steve Thompson * ;* Version 1.0 dated 26-May-81 * ;* * ;****************************************************** org 100h ;base of tpa ; Storage allocation FDC equ 0F800h ;monitor MEMSZ equ 62 ;memory size CPM equ MEMSZ-2 ;actual CP/M size BIAS equ (CPM-20)*1024 ;offset CCP equ 3400h+BIAS ;base of CCP BDOS equ CCP+806h ;base of BDOS BIOS equ CCP+1600h ;base of BIOS ; CP/M entry points reboot equ 0000h ;system reboot bdosen equ 0005h ;bdos entry point coninp equ 1 ;console input function conout equ 2 ;console output function pstring equ 9 ;print string until $ rstring equ 10 ;read console buffer constat equ 11 ;console status cr equ 0dh ;carriage return lf equ 0ah ;line feed ; MONitor entry points stmode equ FDC+021h ;select floppy operation mode sthdr equ FDC+024h ;select head and drive stsect equ FDC+027h ;select sector recal equ FDC+02ah ;recalibrate currently selected disk seek equ FDC+02dh ;seek/select track read equ FDC+030h ;read from disk rtsto equ FDC+036h ;return addr of ST0 drvst equ FDC+04eh ;get drive status ;* lxi sp,stack ;****************************************************** ;* * ;* request disk number * ;* * ;****************************************************** lxi d,drvmsg call print call getchr sui 030h ;convert from ascii to binary lxi h,driven mov m,a ;and store drive number ;****************************************************** ;* * ;* check disk system ready * ;* * ;****************************************************** call sthdr ;set drive call drvst ;get status ani 00100000b jnz rc01 ;ok if bit 5 set lxi d,drvnr call print jmp reboot rc01: call recal jz cmdin lxi d,drvrcl call print jmp rc01 ;try again, until successful! ;****************************************************** ;* * ;* disk read * ;* * ;****************************************************** cmdin: ; input command lxi d,promt call print call readcom mov a,l ;number in a cpi 0FFh ;check for null input jz sec1 lxi h,track mov m,a ;store in memory sec1: call crlf lxi d,proms ;repeat for sector call print call readcom mov a,l ;number in a cpi 0FFh ;check for null input jz side1 lxi h,sector mov m,a ;store in memory side1: call crlf lxi d,promsd;repeat for side call print call readcom mov a,l ;number in a cpi 0FFh ;check for null input jz endinp rlc rlc ;rotate to bit 2 lxi h,driven add m ;add drive number lxi h,sideno mov m,a ;store in memory endinp: call crlf call place ;print place for read call crlf readsk: ; check if single or double density area lxi h,track mov a,m ora a jnz dd ;not track 00, then jump lxi h,sideno mov a,m ani 04H ;check bit 2 jnz dd ;and not side 0, then jump ; set count for SD at 128 lxi h,count mvi m,128 ; select single density disk mvi a,00h call stmode jmp select ; set count for DD at 256 dd: lxi h,count mvi m,00h ; select double density disk mvi a,040h call stmode ; select disk drive select: lxi h,sideno mov a,m call sthdr ; track lxi h,tratry mvi m,0FBh ;set to terminal count of 5 trrcnt: lxi h,track mov a,m call seek jz loopsc call terror ;print error lxi h,tratry inr m ;increment number of tries jnz trrcnt ;try again? loopsc: ; sector lxi h,sector mov a,m ;load this sector number call stsect ;set this sector number ; read from this sector lxi h,retry mvi m,0F6h ;set count to 10 reagn: mvi e,1 ;1 sector lxi h,buff ;from buff call read ;read jz recnt call rerror ;print error lxi h,retry inr m ;increment number of tries jnz reagn call prend jmp cmdin ;if read error then miss comparison recnt: ; print buffer area call printbuff jmp cmdin ; ;***************************************************** ;* * ;* utility routines for console i/o * ;* * ;***************************************************** getchr: ;read next console character into reg a mvi c,coninp call bdosen ret putchr: ;write a caracter from to the console mvi c,conout mov e,a call bdosen ret crlf: ;send a and to the console mvi a,cr call putchr mvi a,lf call putchr ret readcom: ; reads a line of input from the console, and converts ; what is assumed to be a decimal number into a 16bit ; binary, and puts it in HL, a non-numeric ends input. mvi c,rstring lxi d,conbuf call bdos ;read command line ; check if input is present lxi h,consiz mov a,m ora a jnz ntblk ;if length not zero, jump lxi h,00FFh ret ; command line is present, scan it ntblk: lxi h,0 ;start with 0000 lxi d,conlin;command line readc: ldax d ;next command character inx d ;to next command position ora a ;cannot be end of command jz ret0 ;return if end of command line ; not zero, numeric? sui '0' cpi 10 ;carry if numeric jnc ret0 ;return if non-numeric character ; add-in next digit dad h ;*2 mov c,l mov b,h ;bc = value * 2 dad h ;*4 dad h ;*8 dad b ; + *2 = *10 add l ;+digit mov l,a jnc readc ;for another character inr h ;overflow jmp readc ;for another character ret0: push h ;save result lxi h,consiz mov a,m ;a is set to current used size of buffer clrcnt: inx h ;increment buffer pointer mvi m,0 ;set buffer to 0 dcr a jnz clrcnt pop h ;recover answer ret ;return when cleared enough prend: ; print terminated message lxi d,termsg call print call crlf ret printbuff: ; print disk buffer area lxi h,count mov b,m ;set up count lxi h,buff ;set up buffer address prcnt0: mov a,m ;bring in data push h ;store hl push b ;store b cpi 07Fh jm p1ok ;if 7F or less, jump mvi a,'|' ;otherwise print as | jmp pok p1ok: cpi 01Fh jp pok ;if >1F then jump cpi 09h jz pok ;ok if 09h, TAB cpi 0Ah jz pok ;0k if 0Ah, LF cpi 0Dh jz pok ;ok if 0Dh, CR mvi a,'~' ;else alter to ~ pok: call putchr ;print data pop b ;recover b pop h ;recover hl inx h ;increment buffer address dcr b ;decrement counter jnz prcnt0 call crlf ; repeat print in hexadecimal lxi h,count mov b,m ;set up count lxi h,buff ;set up buffer address prcnt1: mov c,m ;bring in data push h ;store hl push b ;store b call putnum ;print data pop b ;recover b pop h ;recover hl inx h ;increment buffer address dcr b ;decrement counter jnz prcnt1 call crlf ret print: ;print the buffer addressed by until $ mvi c,pstring call bdosen ret terror: push psw ;save accumulator, fault code lxi d,tmsg call print jmp eplace rerror: push psw ;save accumulator, fault code lxi d,rmsg call print eplace: pop psw ;recover fault code mov c,a call b8$ash xchg call print call place call crlf ret place: ; print place of error lxi d,msg0 call print lxi h,track mov c,m call putnum lxi d,msg1 call print lxi h,sector mov c,m call putnum lxi d,msg2 call print lxi h,sideno mov a,m ani 00000100b mvi c,1 jnz place1 mvi c,0 place1 call putnum ret putnum: call b8$ash xchg call print ret b8$ash: ;converts 8bit binary to hexadecimal ascii code ;8IT BINARY VALUE IS PASSED THRO' REG C ;ON ENTRY HL IS SET TO BUFFER AREA WHERE ;ASCII HEX CODES ARE TO BE PLACED, ;A $ IS PLACED AT THE END OF THE BUFFER FOR USE WITH 'PRINT' LXI H,BUFB8$ASH ;Load buffer address to HL MVI A,0F0H ;Set mask for first 4 bits ANA C RRC ;Rotate to RH 4 bits RRC RRC RRC CALL CVERT ;Convert to Ascii code MVI A,0FH ;Mask for 2n 4 bits ANA C CALL CVERT DCX H ;Reset HL DCX H RET CVERT ADI 30H ;Convert to Ascii 0-15 CPI 3AH JM JUMP1 ADI 7 ;Convert 10-15 to A-F JUMP1 MOV M,A ;Store in buffer INX H RET BUFB8$ASH DS 2 DB '$' ;***************************************************** ;* * ;* string data area for console messages * ;* * ;***************************************************** drvmsg: db 'input drive number 0/1 ?$' drvnr: db 13,10,'Drive not ready$' drvrcl: db 13,10,'Recalibration error on drive$' promt: db 13,10,'Input read position',13,10,'track no ? $' proms: db 'sector ? $' promsd: db 'side 0/1 ? $' tmsg: db 'track seek/select error$' rmsg: db 'read error $' termsg: db 'tries terminated on count$' msg0: db ' at track $' msg1: db ', sector $' msg2: db ', side $' spmsg: db ' $' space1$: db ' $' trkmsg: db 'track $' ;***************************************************** ;* * ;* fixed and vaiable data area * ;* * ;***************************************************** driven: ds 1 ;drive number sideno: ds 1 ;drive and side selected track: ds 1 ;track selected sector: ds 1 ;sector selected tries: ds 1 ;number of times thro' program count: ds 1 ;counter, 128 for SD, 256 for DD tratry: ds 1 ;number of track seek tries retry: ds 1 ;number of read disk tries buff: ds 256 ;disk buffer area conbuf: db conlen ;length of console buffer consiz: ds 1 ;resulting size after read conlin: ds 32 ;length 32 buffer conlen equ $-consiz ; ds 64 ;32level stack stack: end