;SETDISK - Utility for viewing and assigning logical drives to physical drives ; on my 8080 computer. ; ;Version 1.0 ;08-19-2024 ;Jerry Davis ; CPU 8080 ;Specify architecture PAGE 0 ;Turn off page breaks in listings ; ; ;BIOS Routines ; wboot equ 0f503h ;warm start const equ 0f506h ;console status conin equ 0f509h ;console character in conout equ 0f50ch ;console character out seldsk equ 0f51bh ;select disk settrk equ 0f51eh ;set track number setsec equ 0f521h ;set sector number setdma equ 0f524h ;set dma address read equ 0f527h ;read disk write equ 0f52ah ;write disk ; ; ;BIOS Variables ; drives equ 4 ;number of drives in the system ;diskmap equ 0ffdbh ;physical disk to virtual disk translation diskmap equ 0ffdeh ;physical disk to virtual disk translation ; ; ;BDOS Variables ; tailcnt equ 80h ;Length of command line options tailstr equ 81h ;null terminated command line options ; ; org 100h ; ; start: lxi d, msg_start ;point to start message call print ;print it lda tailcnt ;any command line options? ora a ;set flags jnz st000 ;Get parameters and set drives call status ;print current drive assignments ret ;return to CCP ; st000: call getpdrive ;get physical drive call getvdrive ;get virtual drive lda pdrive ;get stored physical drive cpi 0ffh ;invalid? jz error ;print invalid param message and exit lda vdrive ;get stored virtual drive cpi 0ffh ;invalid? jz error ;print invalid param message and exit lxi h, diskmap ;point to first physical drive lda pdrive ;get stored physical drive st001: cpi 0 ;is it zero yet? jz st002 ;update physical drive with virtual drive inx h ;point to next physical drive dcr a ;decrement pdrive counter jmp st001 ;do over st002: lda vdrive ;get stored physical drive mov m, a ;save vdrive in pdrive call status ;print current drive assignments jmp 0 ;warm start ; ; ;Print status of pdisk to vdisk map ; status: call getvols ;get volume labels lda volerr ;check for volume label error cpi 0 ;Success? jz stat001 ;move on if no error mvi c, bclose ;bdos close function call lxi d, volfcb ;point to volume FCB call bdos ;close the file lxi d, msg_volerr ;point to volume label error call print ;print it stat001: lxi h, diskmap ;point to drive map stat002: call statline ;print drive A map and label lda count ;get drive counter cpi drives-1 ;done? jz statexit ;exit if done inr a ;increment counter sta count ;save it inx h ;point to next drive jmp stat002 ;do again statexit: lxi d, msg_crlf ;point to new line call print ;print it ret ;done ; ; statline: lxi d, msg_crlf ;point to new line call print ;print it lxi d, msg_pdisk ;point to physical disk heading call print ;print it lda count ;get drive counter adi 'A' ;make drive letter mov c, a ;move it to C call conout ;print it lxi d, msg_vdisk ;point to virtual disk heading call print ;print it mov a, m ;get virtual disk number mov c, a ;put it in C call print_dec ;print it mov a, m ;get virtual disk number lxi d, msg_label ;point to label heading call print ;print it lda volerr ;check for label error cpi 1 ;errored out? jz slexit ;skip it mov a, m ;get virtual disk number push h ;save HL on the stack call getlabel ;get the volume label in DE pop h ;get HL from the stack call print ;print it slexit: ret ; ; getlabel: lxi h, labels ;point to labels list lxi b, 16 ;label increment gl001: cpi 0 ;done? jz glexit ;if so then exit dad b ;move pointer to next label dcr a ;decrement vdrive counter jmp gl001 ;next label glexit: xchg ;put HL in DE ret ;exit ; ; ;Print parameter error message ; error: lxi d, msg_crlf ;point to new line call print ;print it lxi d, msg_usage ;point to physical disk heading call print ;print it call status ;print physical to virtual disk map ret ;return to CCP ; ; ;Get physical drive from parameter string ; getpdrive: lxi h, tailstr ;point to option string getpd01: mov a, m ;get first character cpi 0 ;end of parameter string? rz ;return if end of string cpi 'A' ;is it low drive letter? jc getpd02 ;if less than A try next param character cpi 'E' ;is it low drive letter? jnc getpd02 ;if not try next param character sui 'A' ;convert to hex sta pdrive ;save physical drive ret getpd02: inx h ;point to next parameter char jmp getpd01 ;do again ; ; ;Get virtual drive from parameter string ; getvdrive: lxi h, tailstr ;point to option string getvd01: mov a, m ;get first character cpi 0 ;end of parameter string? rz ;return if end of string cpi '0' ;is it low drive number? jc getvd02 ;if not try next param character cpi ':' ;is it greater than 9? jc getvd03 ;if not check if second digit exists getvd02: inx h ;point to next parameter char jmp getvd01 ;do again getvd03: sui '0' ;convert to hex mov b, a ;save first digit in b inx h ;point to next parameter char mov a, m ;get next digit if any cpi '0' ;is it low drive number? jc getvd04 ;if not convert first digit and exit cpi ':' ;is it greater than 9? jnc getvd04 ;if not convert first digit and exit sui '0' ;convert to hex mov c, a ;save second digit in C mov a, b ;get first digit in A cpi 2h ;greater than one? rnc ;return if it is cpi 0 ;is first digit a zero? jz getdv05 ;if it is skip first digit mov a, c ;get second digit in A adi 0ah ;add in decimal 10 cpi 0fh ;greater than 14? rnc ;return if it is sta vdrive ;save virtual drive ret getvd04: mov a, b ;Get first digit in A sta vdrive ;save virtual drive ret getdv05: mov a, c ;Get second digit in A sta vdrive ;save virtual drive ret ; ; ;Print one or two digit decimal number from 4 bit hex ;Modifies: a, c ; print_dec: mov a, c ;move C into A ani 00fh ;mask off high bits adi 0 ;for decimal adjust daa ;decimal adjust A push psw ;save A on the stack mov c, a ;save it in C ani 0f0h ;mask off low bits jz pd001 ;suppress leading zero rrc ;shift to low bits rrc rrc rrc adi '0' ;convert to ASCII mov c, a ;save it in C call conout ;print it pd001: pop psw ;restore A from the stack ani 00fh ;mask off high bits adi '0' ;convert to ASCII mov c, a ;put it in C call conout ;print it ret ; print: ;print a message on the console ldax d ;get char pointed to by D into A cpi 0 ;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 ; ; ;Open the volumes file 'volumes.dat' and read in the volume ;labels for each virtual disk. ;Returns 0ffh or non-zero on fail, 0 on success. ; bopen equ 15 ;BDOS open function bclose equ 16 ;BDOS close function bread equ 20 ;BDOS sequential read function bsdma equ 26 ;BDOS set DMA bdos equ 5 ;BDOS jump address ; getvols: mvi c, bopen ;bdos open function call lxi d, volfcb ;point to volume FCB call bdos ;open the file cpi 0ffh ;file error? jz gverror ;signal error and exit mvi c, bsdma ;bdos set dma function call lxi d, labels ;point to volumes buffer call bdos ;set dma for volume list mvi c, bread ;bdos read function call lxi d, volfcb ;point to volume fcb call bdos ;read one record cpi 0 ;any errors? jnz gverror ;signal error and exit mvi c, bsdma ;bdos set dma function call lxi d, labels+128 ;point to volumes buffer call bdos ;set dma for volume list mvi c, bread ;bdos read function call lxi d, volfcb ;point to volume fcb call bdos ;read one record cpi 0 ;any errors? jnz gverror ;signal error and exit mvi c, bclose ;bdos close function call lxi d, volfcb ;point to volume FCB call bdos ;close the file cpi 0 ;any errors? jnz gverror ;signal error and exit ret ;done gverror: mvi a, 1 ;signal volume label read error sta volerr ;save it ret ; ; msg_start: dw 0d0ah db 'SETVOL v1.0 - Volume to logical disk assignment' dw 0d0ah db 0 ; msg_pdisk: db 'Logical Disk: ' db 0 ; msg_vdisk: db ' Volume: ' db 0 ; msg_label: db ' Label: ' db 0 ; msg_usage: db 'USAGE: SETVOL ' dw 0d0ah dw 0d0ah db 'drive letter = A..D' dw 0d0ah db 'volume number = 0..14' dw 0d0ah db 0 msg_volerr: db '*** Error reading volume labels!' dw 0d0ah db 0 msg_crlf: dw 0d0ah db 0 ; pdrive db 0ffh ;physical drive number vdrive db 0ffh ;virtual drive number count db 0 ;physical drives to display ; volerr: db 0 ;volume error flag ; volfcb: fcbdisk: db 1 ;always use drive A fcbname: db 'VOLUMES', 20h ;volume labels file name fcbtype: db 'DAT' ;volume labels file type fcbextn: db 0 ;volume labels extent fcbresv: db 0,0 ;reserved fcbrecs: db 0 ;volume labels records used fcbaloc: dw 0,0,0,0,0,0,0,0 ;allocation blocks fcbsrec: db 0 ;sequential record number fcbrrec: dw 0 ;random record number fcbreco: db 0 ;random record overflow ; labels ds 256 ;storage for volume labels ; end