; Logical disk format utility for my 8080 microcomputer ; JWD - v1.0 06/19/2024 ; ; Formats current logical disk (directory only) ; Runs as a CP/M utility program in the TPA area ; ; BIOS defines track 1 sectors 0 through 255 ; as directory. These sectors will be written ; with character 0xe5. ; ; CPU 8080 ;Specify architecture for ASL PAGE 0 ;No page breaks in listing ; MONITOR equ 100h ;System monitor start address ; ; ATA Drive Definitions ; ATA_CS1 equ 40h ;ATA Drive CS1 address ATA_FEATURES equ ATA_CS1+1 ;ATA Drive Feature Register (Write Only) ATA_DRV_HEAD equ ATA_CS1+6 ;ATA Drive Device/Head Register ATA_STATUS equ ATA_CS1+7 ;ATA Drive Status Register (Read Only) ATA_COMMAND equ ATA_CS1+7 ;ATA Drive Command Register (Write Only) ; ;ATA Control Commands ; CMD_SET_FEATURES equ 0EFh ;Set card features (aka 8-bit mode) ; ;ATA Control Settings ; DHR_LBA_MODE equ 40h ;DHR Register enable LBA mode (default is CHS) ; ;ATA Status Register Flage ; STATUS_BSY equ 80h ;Device Busy ; ;ATA Feature Codes ; FEATURE_8BIT_ON equ 01h ;Enable 8-bit transfers in LBA mode ; ; BIOS equates ; ccp equ 0df00h ;base of ccp bdos equ ccp+800h ;base of bdos bios equ ccp+1600h ;base of bios ; ; bios access constants ; boot set bios+3*0 ;cold boot function wboot set bios+3*1 ;warm boot function const set bios+3*2 ;console status function conin set bios+3*3 ;console input function conout set bios+3*4 ;console output function list set bios+3*5 ;list output function punch set bios+3*6 ;punch output function reader set bios+3*7 ;reader input function home set bios+3*8 ;disk home function seldsk set bios+3*9 ;select disk function settrk set bios+3*10 ;set track function setsec set bios+3*11 ;set sector function setdma set bios+3*12 ;set dma function read set bios+3*13 ;read disk function write set bios+3*14 ;write disk function listst set bios+3*15 ;list status function sectran set bios+3*16 ;sector translate ; ; ; Disk driver variables needed ; ; hstact equ 0f950h ;host active flag for deblocking unacnt equ 0f952h ;unallocated record count for deblocking disk00 equ 0ffdeh ;physical disk to virtual disk translation ; ; maxdrv equ 15 ; ; ; Write types ; wrall equ 0 ;write to allocated wrdir equ 1 ;write to directory wrual equ 2 ;write to unallocated ; ; org 1000h ; ; format lxi d, frmtmsg ;Point to start message call print ;Print it frmt01 call conin ;Get yes or no ani 0dfh ;Make it upper case cpi 'Y' ;Is it 'Y'? jz frmt02 ;Do format cpi 'N' ;Is it 'N'? jz frmt10 ;If not print abort message and exit jmp frmt01 ;Ask again ; ;Set drive for LBA mode and 8 bit transfers ; frmt02 in ATA_DRV_HEAD ;Get current DHR bits ori DHR_LBA_MODE ;Set the LBA mode bit out ATA_DRV_HEAD ;Write bits to the DHR register mvi a, FEATURE_8BIT_ON ;Get feature code for 8-bit mode out ATA_FEATURES ;Write 8-bit feature code to features register mvi a, CMD_SET_FEATURES ;Get ready for Features command out ATA_COMMAND ;Request Set Features command atabusy in ATA_STATUS ;Get ATA status ani STATUS_BSY ;Mask on busy bit jnz atabusy ;If busy check again ; ;Initialize sector buffer ; lxi b, secbuf ;Point to default disk buffer call setdma ;Set dma to sector buffer mvi d, 80h ;Disk buffer length mvi a, 0e5h ;Format character frmt03 stax b ;Save it in disk buffer inx b ;Point to next buffer character dcr d ;Count down jnz frmt03 ;Do it again ; ;Write sector buffer to each logical disk ; mvi a, 0 ;Set up disk driver sta hstact ;host buffer inactive sta unacnt ;clear unalloc count sta disk00 ;Start with disk 0 mov c, a ;Always format drive 0 (mapped to other drives) call seldsk ;Select the disk frmt04 lxi d, frmtdrv ;Point to drive message call print ;Print it lda disk00 ;Get current drive adi 'A' ;Calculate drive letter mov c, a ;Transfer to register c call conout ;Print it mvi c, 0dh ;Carriage return call conout ;Print it mvi c, 0ah ;Line feed call conout ;Print it frmt05 lxi b, 1 ;Select track 1 (directory) call settrk lxi h, seccnt ;Point to sector counter mvi c, 00 ;Select sector 0 mov m, c ;Save it in the counter frmt06 call setsec ;Select the sector mvi c, wrdir ;Don't buffer call write ;Write the formatted sector ora a ;Did write succeed? jnz frmt09 ;Print error message and exit mvi c, '.' ;Status character call conout ;Print it lxi h, seccnt ;Point to sector counter mov c, m ;Get current sector inr c ;Count up mov a, c ;Put sector count in A cpi 0 ;End of directory? jz frmt07 ;Next drive if end of directory mov m, c ;Save sector counter jmp frmt06 ;Do next sector frmt07 lda disk00 ;Get current disk inr a ;Next drive cpi maxdrv ;Finished last drive? jz frmt08 ;Done with formatting sta disk00 ;Otherwise do again jmp frmt04 ;Format next drive ; ;Print successful format message ; frmt08 lxi d, frmtenm ;Point to end of formatting call print ;Print it jmp frmt11 ;Exit ; ;Print write error message ; frmt09 lxi d, frmterr ;Point to error message call print ;Print it jmp frmt11 ; ;Print abort message ; frmt10 lxi d, frmtabt ;Point to abort message call print ; ;Print exit message and jump to monitor ; frmt11 lxi d, frmtexm ;Point to exit message call print ;Print it jmp MONITOR ;Jump to monitor ; ;Print string utility ;Pointer to null terminated string in de ; print: ldax d ;Print a message on the console ora a ;End of string? jz pend ;Exit if end of string mov c, a ;Move shar into C for console out call conout ;Print it inx d ;Point to next character jmp print ;Repeat pend: ret ;And exit ; ;Console messages ; frmtmsg db 'Disk formatter v1.0' dw 0d0ah db 'Warning! This will format all logical drives.' dw 0d0ah db 'ARE YOU SURE (Y/N)?' dw 0d0ah db 0 frmtdrv dw 0d0ah db 'Formatting drive ' db 0 frmterr dw 0d0ah db 'Error formatting drive!' dw 0d0ah db 0 frmtenm dw 0d0ah db 'Format completed successfully.' dw 0d0ah db 0 frmtabt db 'Format aborted.' dw 0d0ah db 0 frmtexm db 'Returning to monitor.' dw 0d0ah db 0 ; ;Sector counter ; seccnt db 0 ; cdisk db 0 ; secbuf db 128 ; end