mirror of https://github.com/wwarthen/RomWBW.git
committed by
GitHub
18 changed files with 864 additions and 19 deletions
@ -1,5 +1,5 @@ |
|||
SUBDIRS = HTalk XM FDU FAT Tune Test ZMP ZMD Dev VGM cpuspd reboot Survey BBCBASIC copysl \
|
|||
sysgen syscopy assign format talk mode rtc timer ZDE |
|||
slabel sysgen syscopy assign format talk mode rtc timer ZDE |
|||
TOOLS =../../Tools |
|||
|
|||
include $(TOOLS)/Makefile.inc |
|||
|
|||
@ -0,0 +1,10 @@ |
|||
@echo off |
|||
setlocal |
|||
|
|||
set TOOLS=../../../Tools |
|||
set PATH=%TOOLS%\tasm32;%PATH% |
|||
set TASMTABS=%TOOLS%\tasm32 |
|||
|
|||
tasm -t80 -g3 -fFF slabel.asm slabel.com slabel.lst || exit /b |
|||
|
|||
copy /Y slabel.com ..\..\..\Binary\Apps\ || exit /b |
|||
@ -0,0 +1,6 @@ |
|||
@echo off |
|||
setlocal |
|||
|
|||
if exist *.com del *.com |
|||
if exist *.lst del *.lst |
|||
if exist *.bin del *.bin |
|||
@ -0,0 +1,7 @@ |
|||
OBJECTS = slabel.com |
|||
DEST = ../../../Binary/Apps |
|||
TOOLS =../../../Tools |
|||
|
|||
USETASM=1 |
|||
|
|||
include $(TOOLS)/Makefile.inc |
|||
@ -0,0 +1,761 @@ |
|||
;============================================================================== |
|||
; SLICE LABEL - Update Disk Labels |
|||
; Version December-2024 |
|||
;============================================================================== |
|||
; |
|||
; Author: Mark Pruden |
|||
;______________________________________________________________________________ |
|||
; |
|||
; Usage: |
|||
; SLABEL [unit.slice,label] [/?] |
|||
; ex: SLABEL Display current list of Labels |
|||
; SLABEL unit.slice=label Assign a disk Label to the Slice on Unit |
|||
; SLABEL /? Display version and usage |
|||
; |
|||
; Operation: |
|||
; Print and Assign a Disk Label to a Hard Disk Slice. |
|||
; |
|||
; Technical: |
|||
; On the third sector of "bootable" Disk Slice there is metadata used by RomWBW to know how |
|||
; to boot the OS found on the slice. This includes a Label for the volume, which is printed |
|||
; out by RomWBW during the boot process. |
|||
; Note this label is not associated to any label the OS may assign to the volume. |
|||
; See loader.asm in each of the O/S directories e.g. /src/CPM22 which describe these sectors |
|||
; |
|||
; This ony works on slices which have existing media information in the third sector. |
|||
; There is no capabiity to write this information on demand. |
|||
; |
|||
; known Issues: |
|||
; - Listing the slabel for all slices can be time consuming, because of the use of the EXT_MEDIA |
|||
; function call. This function reads the partition table (on each call) to assert (if valid) |
|||
; the LBA location of the requested slice. Ideally we would only need to read the partition |
|||
; table once (per device), and work out all the LBA's from this single read. |
|||
; Note this doesnt omit the fact that the 3 rd sector of each slice wold need to be read regarless. |
|||
; To slightly reduce some IO only slices < 64 are considered. |
|||
; |
|||
; This code will only execute on a Z80 CPU (or derivitive) |
|||
; This code requirs the use of HBIOS |
|||
; |
|||
;______________________________________________________________________________ |
|||
; |
|||
; Change Log: |
|||
; 2024-12-11 [MAP] Started - Reboot v1.0 used as the basis for this code |
|||
; 2024-12-14 [MAP] Initial 0.9 alpha with basic working functionality |
|||
; 2025-04-21 [MAP] Initial v1.0 release for distribution, fixing all issues |
|||
;______________________________________________________________________________ |
|||
; |
|||
; Include Files |
|||
; |
|||
#include "../../ver.inc" ; to ensure it is the correct ver |
|||
#include "../../HBIOS/hbios.inc" |
|||
; |
|||
;=============================================================================== |
|||
; |
|||
; General operational equates (should not requre adjustment) |
|||
; |
|||
stksiz .equ $40 ; Working stack size |
|||
; |
|||
restart .equ $0000 ; CP/M restart vector |
|||
bdos .equ $0005 ; BDOS invocation vector |
|||
cmdbuf .equ $0081 ; CPM command buffer |
|||
; |
|||
bf_sysreset .equ $F0 ; restart system |
|||
bf_sysres_int .equ $00 ; reset hbios internal |
|||
bf_sysres_warm .equ $01 ; warm start (restart boot loader) |
|||
; |
|||
ident .equ $FFFE ; loc of RomWBW HBIOS ident ptr |
|||
; |
|||
sigbyte1 .equ $A5 ; 1st sig byte boot info sector (bb_sig) |
|||
sigbyte2 .equ $5A ; 2nd sig byte boot info sector (bb_sig) |
|||
; |
|||
labelterm .equ '$' ; terminating charater for disk label |
|||
; |
|||
;=============================================================================== |
|||
; |
|||
.org $0100 ; standard CP/M TPA executable |
|||
; |
|||
ld (stksav),sp ; save stack |
|||
ld sp,stack ; set new stack |
|||
; |
|||
ld de,str_banner |
|||
call prtstr ; print the banner |
|||
; |
|||
call init ; initialize |
|||
jr nz,exit ; abort if init fails |
|||
; |
|||
call main ; do the real work |
|||
; |
|||
exit: |
|||
call crlf ; print terminating crlf |
|||
ld sp,(stksav) ; restore stack to prior state |
|||
jp restart ; return to CP/M via restart |
|||
; |
|||
;=============================================================================== |
|||
; Initialization |
|||
; |
|||
init: |
|||
; check for UNA (UBIOS) |
|||
ld a,($FFFD) ; fixed location of UNA API vector |
|||
cp $C3 ; jp instruction? |
|||
jr nz,initwbw ; if not, not UNA |
|||
ld hl,($FFFE) ; get jp address |
|||
ld a,(hl) ; get byte at target address |
|||
cp $FD ; first byte of UNA push ix instruction |
|||
jr nz,initwbw ; if not, not UNA |
|||
inc hl ; point to next byte |
|||
ld a,(hl) ; get next byte |
|||
cp $E5 ; second byte of UNA push ix instruction |
|||
jr nz,initwbw ; if not, not UNA |
|||
jp err_una ; UNA not supported |
|||
; |
|||
initwbw: |
|||
; get location of config data and verify integrity |
|||
ld hl,(ident) ; HL := adr or RomWBW HBIOS ident |
|||
ld a,(hl) ; get first byte of RomWBW marker |
|||
cp 'W' ; match? |
|||
jp nz,err_inv ; abort with invalid config block |
|||
inc hl ; next byte (marker byte 2) |
|||
ld a,(hl) ; load it |
|||
cp ~'W' ; match? |
|||
jp nz,err_inv ; abort with invalid config block |
|||
inc hl ; next byte (major/minor version) |
|||
ld a,(hl) ; load it |
|||
cp rmj << 4 | rmn ; match? |
|||
jp nz,err_ver ; abort with invalid os version |
|||
; |
|||
initz: |
|||
; initialization complete |
|||
xor a ; signal success |
|||
ret ; return |
|||
; |
|||
;=============================================================================== |
|||
; Main Execution |
|||
; |
|||
main: |
|||
call initdiskio ; initi DiskIO routines (bank ID) |
|||
; |
|||
ld de,cmdbuf ; start of command input buffer |
|||
call skipws ; skip whitespace on cmd line |
|||
; |
|||
ld a,(de) ; get first non-ws char |
|||
or a ; test for terminator, no parms |
|||
jr z,prtslc ; if so, print details, and return |
|||
; |
|||
call isnum ; do we have a number? |
|||
jp z,setlabel ; if so, then we are setting Label. |
|||
; |
|||
jp usage ; otherwise print usage and return |
|||
ret ; and exit |
|||
; |
|||
;=============================================================================== |
|||
; Print Usage /? Information |
|||
; |
|||
usage: |
|||
ld de,str_usage ; display the cmd options for this utility |
|||
call prtstr |
|||
; |
|||
ret ; exit back out to CP/M CCP |
|||
; |
|||
;=============================================================================== |
|||
; Print list of all slices |
|||
; |
|||
prtslc: |
|||
ld de,PRTSLC_HDR ; Header for list of Slices |
|||
call prtstr ; Print It |
|||
; |
|||
ld bc,BC_SYSGET_DIOCNT ; FUNC: SYSTEM INFO GET DISK DRIVES |
|||
rst 08 ; E := UNIT COUNT |
|||
; |
|||
ld b,e ; MOVE Disk CNT TO B FOR LOOP COUNT |
|||
ld c,0 ; C WILL BE UNIT INDEX |
|||
prtslc1: |
|||
ld a,b ; loop counter |
|||
or a ; set flags |
|||
ret z ; IF no more drives, finished |
|||
; |
|||
ld a,c ; unit index |
|||
ld (currunit),a ; store the unit number |
|||
; |
|||
push bc ; save loop vars |
|||
call prtslc2 ; for each disk Unit, print its details |
|||
pop bc ; restore loop variables |
|||
; |
|||
inc c ; bump the unit number |
|||
djnz prtslc1 ; main disk loop |
|||
; |
|||
ret ; loop has finished |
|||
; |
|||
;------------------------------------------------------------------------------- |
|||
; Print list of All Slices for a given Unit |
|||
; |
|||
prtslc2: |
|||
; get the media infor |
|||
ld b,BF_DIOMEDIA ; get media information |
|||
ld e,1 ; with media discovery |
|||
rst 08 ; do media discovery |
|||
ret nz ; an error |
|||
; |
|||
ld a,MID_HD ; hard disk |
|||
cp e ; is it hard disk |
|||
ret nz ; if not noting to do |
|||
; |
|||
; setup the loop |
|||
ld b,64 ; arbitrary (?) number of slices to check. |
|||
; NOTE: could be higher, but each slice check has disk IO |
|||
ld c,0 ; starting at slice 0 |
|||
; |
|||
prtslc2a: |
|||
ld a,c ; slice number |
|||
ld (currslice),a ; save slice number |
|||
; |
|||
push bc ; save loop |
|||
call prtslc3 ; print detals of the slice |
|||
pop bc ; restore loop |
|||
ret nz ; if error dont continie |
|||
; |
|||
inc c ; next slice number |
|||
djnz prtslc2a ; loop if more slices |
|||
; |
|||
ret ; return from Slice Loop |
|||
; |
|||
;------------------------------------------------------------------------------- |
|||
; Print details of a Slice for a given Unit/Slice |
|||
; |
|||
prtslc3: |
|||
; get the details of the device / slice |
|||
ld a,(currunit) |
|||
ld d,a ; unit |
|||
ld a,(currslice) |
|||
ld e,a ; slice |
|||
ld b,BF_EXTSLICE ; EXT function to check compute slice offset |
|||
rst 08 ; noting this call checks partition table. |
|||
ret NZ ; an error, for lots of reasons, e.g. Slice not valid |
|||
; |
|||
call thirdsector ; point to the third sector of partition |
|||
; |
|||
call diskread ; do the sector read |
|||
ret nz ; read error. exit the slice loop |
|||
; |
|||
; Check signature |
|||
ld bc,(bb_sig) ; get signature read |
|||
ld a,sigbyte1 ; expected value of first byte |
|||
cp b ; compare |
|||
jr nz,prtslc5 ; ignore missing signature and loop |
|||
ld a,sigbyte2 ; expected value of second byte |
|||
cp c ; compare |
|||
jr nz,prtslc5 ; ignore missing signature and loop |
|||
; |
|||
; Print volume label string at HL, '$' terminated, 16 chars max |
|||
ld a,(currunit) |
|||
call prtdecb ; print unit number as decimal |
|||
call pdot ; print a DOT |
|||
ld a,(currslice) |
|||
call prtdecb |
|||
ld a,' ' |
|||
call cout ; print a space |
|||
call cout ; print a space |
|||
ld hl,bb_label ; point to label |
|||
call pvol ; print it |
|||
call crlf |
|||
; |
|||
prtslc5: |
|||
xor a |
|||
ret |
|||
; |
|||
;------------------------------------------------------------------------------- |
|||
; Print volume label string at HL, '$' terminated, 16 chars max |
|||
; |
|||
pvol: |
|||
ld b,16 ; init max char downcounter |
|||
pvol1: |
|||
ld a,(hl) ; get next character |
|||
cp labelterm ; set flags based on terminator $ |
|||
inc hl ; bump pointer regardless |
|||
ret z ; done if null |
|||
call cout ; display character |
|||
djnz pvol1 ; loop till done |
|||
ret ; hit max of 16 chars |
|||
; |
|||
;=============================================================================== |
|||
; Set Label Information onto disk |
|||
; |
|||
setlabel: |
|||
call getnum ; parse a number |
|||
jp c,err_parm ; handle overflow error |
|||
ld (currunit),a ; save boot unit |
|||
xor a ; zero accum |
|||
ld (currslice),a ; save default slice |
|||
call skipws ; skip possible whitespace |
|||
ld a,(de) ; get separator char |
|||
or a ; test for terminator |
|||
jr z,err_parm ; if so, incomplete |
|||
cp '=' ; otherwise, is ','? |
|||
jr z,setlabel4 ; if so, skip the Slice parm |
|||
cp '.' ; otherwise, is '.'? |
|||
jp NZ,err_parm ; if not, format error |
|||
; |
|||
inc de ; bump past separator |
|||
call skipws ; skip possible whitespace |
|||
call isnum ; do we have a number? |
|||
jp nz,err_parm ; if not, format error |
|||
call getnum ; get number |
|||
jp c,err_parm ; handle overflow error |
|||
ld (currslice),a ; save boot slice |
|||
setlabel3: |
|||
call skipws ; skip possible whitespace |
|||
ld a,(de) ; get separator char |
|||
or a ; test for terminator |
|||
jr z,err_parm ; if so, then an error |
|||
cp '=' ; otherwise, is ','? |
|||
jp nz,err_parm ; if not, format error |
|||
setlabel4: |
|||
inc de ; bump past separator |
|||
call skipws ; skip possible whitespace |
|||
ld (newlabel),de ; address of disk label after '=' |
|||
; |
|||
ld a,(currunit) ; passing boot unit |
|||
ld d,a |
|||
ld a,(currslice) ; and slice |
|||
ld e,a |
|||
ld b,BF_EXTSLICE ; HBIOS func: SLICE CALC - extended |
|||
rst 08 ; info for the Device, and Slice |
|||
; |
|||
; Check errors from the Function |
|||
cp ERR_NOUNIT ; compare to no unit error |
|||
jp z,err_nodisk ; handle no disk err |
|||
cp ERR_NOMEDIA ; no media in the device |
|||
jp z,err_nomedia ; handle the error |
|||
cp ERR_RANGE ; slice is invalid |
|||
jp z,err_badslice ; bad slice, handle err |
|||
or a ; any other error |
|||
jp nz,err_diskio ; handle as general IO error |
|||
; |
|||
call thirdsector ; point to the third sector of partition |
|||
; |
|||
call diskread ; read the sector |
|||
jp nz,err_diskio ; abort on error |
|||
; |
|||
; Check signature |
|||
ld de,(bb_sig) ; get signature read |
|||
ld a,sigbyte1 ; expected value of first byte |
|||
cp d ; compare |
|||
jp nz,err_sig ; handle error |
|||
ld a,sigbyte2 ; expected value of second byte |
|||
cp e ; compare |
|||
jp nz,err_sig ; handle error |
|||
; |
|||
ld b,16 ; loop down counter (max size of label) |
|||
ld de,(newlabel) ; reading from cmd line |
|||
ld hl,bb_label ; writing to disk label in sector buffer |
|||
updatelabel: |
|||
ld a,(de) ; read input |
|||
or a ; look for string terminator |
|||
jr z,updatelabel2 ; if terminator then complete |
|||
ld (hl),a ; store char in sector buff |
|||
inc de ; update pointers |
|||
inc hl |
|||
djnz updatelabel ; loop for next character |
|||
updatelabel2: |
|||
ld a,labelterm |
|||
ld (hl),a ; store the final terminator $ char |
|||
writelabel: |
|||
; write the sector |
|||
ld hl,(lba) ; lba, low word, same as read sector |
|||
ld de,(lba+2) ; lba, high word |
|||
call diskwrite ; write the sector back to disk |
|||
jp nz,err_diskio ; abort on error |
|||
; |
|||
; print the outcome. |
|||
ld de,PRTSLC_HDR ; Header for list of Slices |
|||
call prtstr ; Print header |
|||
call prtslc3 ; print updated label for unit/slice |
|||
; |
|||
ret |
|||
; |
|||
;------------------------------------------------------------------------------- |
|||
; advance the DE HL LBA sector by 2, ie third sector |
|||
; |
|||
thirdsector: |
|||
ld bc,2 ; sector offset |
|||
add hl,bc ; add to LBA value low word |
|||
jr nc,sectornum ; check for carry |
|||
inc de ; if so, bump high word |
|||
sectornum: |
|||
ld (lba),hl ; update lba, low word |
|||
ld (lba+2),de ; update lba, high word |
|||
ret |
|||
; |
|||
;=============================================================================== |
|||
; Error Handlers |
|||
; |
|||
err_una: |
|||
ld de,str_err_una |
|||
jr err_ret |
|||
err_inv: |
|||
ld de,str_err_inv |
|||
jr err_ret |
|||
err_ver: |
|||
ld de,str_err_ver |
|||
jr err_ret |
|||
err_parm: |
|||
ld de,str_err_parm |
|||
jr err_ret |
|||
err_nodisk: |
|||
ld de,str_err_nodisk |
|||
jr err_ret |
|||
err_nomedia: |
|||
ld de,str_err_nomedia |
|||
jr err_ret |
|||
err_badslice: |
|||
ld de,str_err_badslc |
|||
jr err_ret |
|||
err_sig: |
|||
ld de,str_err_sig |
|||
jr err_ret |
|||
err_diskio: |
|||
ld de,str_err_diskio |
|||
jr err_ret |
|||
err_ret: |
|||
call crlf2 |
|||
call prtstr |
|||
or $FF ; signal error |
|||
ret |
|||
; |
|||
;=============================================================================== |
|||
; Utility Routines |
|||
;------------------------------------------------------------------------------- |
|||
; Print a dot on console |
|||
; |
|||
pdot: |
|||
push af |
|||
ld a,'.' |
|||
call cout |
|||
pop af |
|||
ret |
|||
; |
|||
;------------------------------------------------------------------------------- |
|||
; Print character in A without destroying any registers |
|||
; |
|||
prtchr: |
|||
cout: |
|||
push af ; save registers |
|||
push bc |
|||
push de |
|||
push hl |
|||
ld e,a ; character to print in E |
|||
ld c,$02 ; BDOS function to output a character |
|||
call bdos ; do it |
|||
pop hl ; restore registers |
|||
pop de |
|||
pop bc |
|||
pop af |
|||
ret |
|||
; |
|||
;------------------------------------------------------------------------------- |
|||
; Start a newline on console (cr/lf) |
|||
; |
|||
crlf2: |
|||
call crlf ; two of them |
|||
crlf: |
|||
push af ; preserve AF |
|||
ld a,13 ; <CR> |
|||
call prtchr ; print it |
|||
ld a,10 ; <LF> |
|||
call prtchr ; print it |
|||
pop af ; restore AF |
|||
ret |
|||
; |
|||
;------------------------------------------------------------------------------- |
|||
; Print a zero terminated string at (de) without destroying any registers |
|||
; |
|||
prtstr: |
|||
push af |
|||
push de |
|||
; |
|||
prtstr1: |
|||
ld a,(de) ; get next char |
|||
or a |
|||
jr z,prtstr2 |
|||
call prtchr |
|||
inc de |
|||
jr prtstr1 |
|||
; |
|||
prtstr2: |
|||
pop de ; restore registers |
|||
pop af |
|||
ret |
|||
; |
|||
;------------------------------------------------------------------------------- |
|||
; Print value of a in decimal with leading zero suppression |
|||
; |
|||
prtdecb: |
|||
push hl |
|||
push af |
|||
ld l,a |
|||
ld h,0 |
|||
call prtdec |
|||
pop af |
|||
pop hl |
|||
ret |
|||
; |
|||
;------------------------------------------------------------------------------- |
|||
; Print value of HL in decimal with leading zero suppression |
|||
; |
|||
prtdec: |
|||
push bc |
|||
push de |
|||
push hl |
|||
ld e,'0' |
|||
ld bc,-10000 |
|||
call prtdec1 |
|||
ld bc,-1000 |
|||
call prtdec1 |
|||
ld bc,-100 |
|||
call prtdec1 |
|||
ld c,-10 |
|||
call prtdec1 |
|||
ld e,0 |
|||
ld c,-1 |
|||
call prtdec1 |
|||
pop hl |
|||
pop de |
|||
pop bc |
|||
ret |
|||
prtdec1: |
|||
ld a,'0' - 1 |
|||
prtdec2: |
|||
inc a |
|||
add hl,bc |
|||
jr c,prtdec2 |
|||
sbc hl,bc |
|||
cp e |
|||
jr z,prtdec3 |
|||
ld e,0 |
|||
call cout |
|||
prtdec3: |
|||
ret |
|||
; |
|||
;------------------------------------------------------------------------------- |
|||
; INPUT ROUTINES |
|||
;------------------------------------------------------------------------------- |
|||
; Skip whitespace at buffer adr in DE, returns with first |
|||
; non-whitespace character in A. |
|||
; |
|||
skipws: |
|||
ld a,(de) ; get next char |
|||
or a ; check for eol |
|||
ret z ; done if so |
|||
cp ' ' ; blank? |
|||
ret nz ; nope, done |
|||
inc de ; bump buffer pointer |
|||
jr skipws ; and loop |
|||
; |
|||
;------------------------------------------------------------------------------- |
|||
; Convert character in A to uppercase |
|||
; |
|||
upcase: |
|||
cp 'a' ; if below 'a' |
|||
ret c ; ... do nothing and return |
|||
cp 'z' + 1 ; if above 'z' |
|||
ret nc ; ... do nothing and return |
|||
res 5,a ; clear bit 5 to make lower case -> upper case |
|||
ret ; and return |
|||
; |
|||
;------------------------------------------------------------------------------- |
|||
; Get numeric chars at DE and convert to number returned in A |
|||
; Carry flag set on overflow |
|||
; |
|||
getnum: |
|||
ld c,0 ; C is working register |
|||
getnum1: |
|||
ld a,(de) ; get the active char |
|||
cp '0' ; compare to ascii '0' |
|||
jr c,getnum2 ; abort if below |
|||
cp '9' + 1 ; compare to ascii '9' |
|||
jr nc,getnum2 ; abort if above |
|||
; |
|||
; valid digit, add new digit to C |
|||
ld a,c ; get working value to A |
|||
rlca ; multiply by 10 |
|||
ret c ; overflow, return with carry set |
|||
rlca ; ... |
|||
ret c ; overflow, return with carry set |
|||
add a,c ; ... |
|||
ret c ; overflow, return with carry set |
|||
rlca ; ... |
|||
ret c ; overflow, return with carry set |
|||
ld c,a ; back to C |
|||
ld a,(de) ; get new digit |
|||
sub '0' ; make binary |
|||
add a,c ; add in working value |
|||
ret c ; overflow, return with carry set |
|||
ld c,a ; back to C |
|||
; |
|||
inc de ; bump to next char |
|||
jr getnum1 ; loop |
|||
; |
|||
getnum2: ; return result |
|||
ld a,c ; return result in A |
|||
or a ; with flags set, CF is cleared |
|||
ret |
|||
; |
|||
;------------------------------------------------------------------------------- |
|||
; Is character in A numeric? NZ if not |
|||
; |
|||
isnum: |
|||
cp '0' ; compare to ascii '0' |
|||
jr c,isnum1 ; abort if below |
|||
cp '9' + 1 ; compare to ascii '9' |
|||
jr nc,isnum1 ; abort if above |
|||
cp a ; set Z |
|||
ret |
|||
isnum1: |
|||
or $FF ; set NZ |
|||
ret ; and done |
|||
; |
|||
;------------------------------------------------------------------------------- |
|||
; DISK IO ROUTINES |
|||
;------------------------------------------------------------------------------- |
|||
; Init Disk IO |
|||
; |
|||
initdiskio: |
|||
; Get current RAM bank |
|||
ld b,BF_SYSGETBNK ; HBIOS GetBank function |
|||
RST 08 ; do it via RST vector, C=bank id |
|||
RET NZ ; had to replace this line below. |
|||
ld a,c ; put bank id in A |
|||
ld (BID_USR),a ; put bank id in Argument |
|||
RET |
|||
; |
|||
;------------------------------------------------------------------------------- |
|||
; Read disk sector(s) |
|||
; DE:HL is LBA, B is sector count, C is disk unit |
|||
; |
|||
diskread: |
|||
; |
|||
; Seek to requested sector in DE:HL |
|||
ld a,(currunit) |
|||
ld c,a ; from the specified unit |
|||
set 7,d ; set LBA access flag |
|||
ld b,BF_DIOSEEK ; HBIOS func: seek |
|||
rst 08 ; do it |
|||
ret nz ; handle error |
|||
; |
|||
; Read sector(s) into buffer |
|||
ld a,(currunit) |
|||
ld c,a ; from the specified unit |
|||
ld e,1 ; read 1 sector |
|||
ld hl,(dma) ; read into info sec buffer |
|||
ld d,BID_USR ; user bank |
|||
ld b,BF_DIOREAD ; HBIOS func: disk read |
|||
rst 08 ; do it |
|||
ret ; and done |
|||
; |
|||
;------------------------------------------------------------------------------- |
|||
; WRITE disk sector(s) |
|||
; DE:HL is LBA, B is sector count, C is disk unit |
|||
; |
|||
diskwrite: |
|||
; |
|||
ld a,(currunit) ; disk unit to read |
|||
ld c,a ; put in C |
|||
ld b,1 ; one sector |
|||
; |
|||
; Seek to requested sector in DE:HL |
|||
push bc ; save unit & count |
|||
set 7,d ; set LBA access flag |
|||
ld b,BF_DIOSEEK ; HBIOS func: seek |
|||
rst 08 ; do it |
|||
pop bc ; recover unit & count |
|||
ret nz ; handle error |
|||
; |
|||
; Read sector(s) into buffer |
|||
ld e,b ; transfer count |
|||
ld b,BF_DIOWRITE ; HBIOS func: disk read |
|||
ld hl,(dma) ; read into info sec buffer |
|||
ld d,BID_USR ; user bank |
|||
rst 08 ; do it |
|||
ret ; and done |
|||
; |
|||
;=============================================================================== |
|||
; Constants |
|||
;=============================================================================== |
|||
; |
|||
str_banner .db "\r\n" |
|||
.db "Slice Label, v1.0, April 2025 - M.Pruden",0 |
|||
; |
|||
str_err_una .db " ERROR: UNA not supported by application",0 |
|||
str_err_inv .db " ERROR: Invalid BIOS (signature missing)",0 |
|||
str_err_ver .db " ERROR: Unexpected HBIOS version",0 |
|||
str_err_parm .db " ERROR: Parameter error (SLABEL /? for usage)",0 |
|||
str_err_nodisk .db " ERROR: Disk unit not available",0 |
|||
str_err_nomedia .db " ERROR: Media not present",0 |
|||
str_err_badslc .db " ERROR: Slice specified is illegal",0 |
|||
str_err_sig .db " ERROR: No system image on disk",0 |
|||
str_err_diskio .db " ERROR: Disk I/O failure",0 |
|||
; |
|||
str_usage .db "\r\n\r\n" |
|||
.db " Usage: SLABEL - list current labels\r\n" |
|||
.db " SLABEL unit[.slice]=label - Defines a label\r\n" |
|||
.db " SLABEL /? - Display this help info.\r\n" |
|||
.db " Options are case insensitive.\r\n",0 |
|||
; |
|||
PRTSLC_HDR .TEXT "\r\n\r\n" |
|||
.TEXT "Un.Sl Drive \r\n" |
|||
.TEXT "----- ----------------\r\n" |
|||
.DB 0 |
|||
; |
|||
;=============================================================================== |
|||
; Working data |
|||
;=============================================================================== |
|||
; |
|||
currunit .db 0 ; parameters for disk unit, current unit |
|||
currslice .db 0 ; parameters for disk slice, current slice |
|||
lba .dw 0, 0 ; lba address (4 bytes), of slice |
|||
newlabel .dw 0 ; address of parameter, new label to write |
|||
; |
|||
BID_USR .db 0 ; Bank ID for user bank |
|||
dma .dw bl_infosec ; address for disk buffer |
|||
; |
|||
stksav .dw 0 ; stack pointer saved at start |
|||
.fill stksiz,0 ; stack |
|||
stack .equ $ ; stack top |
|||
; |
|||
;=============================================================================== |
|||
; Disk Buffer |
|||
;=============================================================================== |
|||
; |
|||
; define origin of disk buffer above 8000 for performance. |
|||
.org $8000 |
|||
; |
|||
; Below is copied from ROM LDR |
|||
; Boot info sector is read into area below. |
|||
; The third sector of a disk device is reserved for boot info. |
|||
; |
|||
bl_infosec .equ $ |
|||
.ds (512 - 128) |
|||
bb_metabuf .equ $ |
|||
bb_sig .ds 2 ; signature (0xA55A if set) |
|||
bb_platform .ds 1 ; formatting platform |
|||
bb_device .ds 1 ; formatting device |
|||
bb_formatter .ds 8 ; formatting program |
|||
bb_drive .ds 1 ; physical disk drive # |
|||
bb_lu .ds 1 ; logical unit (lu) |
|||
.ds 1 ; msb of lu, now deprecated |
|||
.ds (bb_metabuf + 128) - $ - 32 |
|||
bb_protect .ds 1 ; write protect boolean |
|||
bb_updates .ds 2 ; update counter |
|||
bb_rmj .ds 1 ; rmj major version number |
|||
bb_rmn .ds 1 ; rmn minor version number |
|||
bb_rup .ds 1 ; rup update number |
|||
bb_rtp .ds 1 ; rtp patch level |
|||
bb_label .ds 16 ; 16 character drive label |
|||
bb_term .ds 1 ; label terminator ('$') |
|||
bb_biloc .ds 2 ; loc to patch boot drive info |
|||
bb_cpmloc .ds 2 ; final ram dest for cpm/cbios |
|||
bb_cpmend .ds 2 ; end address for load |
|||
bb_cpment .ds 2 ; CP/M entry point (cbios boot) |
|||
; |
|||
;=============================================================================== |
|||
; |
|||
.end |
|||
Loading…
Reference in new issue