diff --git a/Binary/Clean.cmd b/Binary/Clean.cmd index b0b248d8..ad11adad 100644 --- a/Binary/Clean.cmd +++ b/Binary/Clean.cmd @@ -2,6 +2,7 @@ setlocal if exist *.bin del *.bin +if exist *.dat del *.dat if exist *.com del *.com if exist *.img del *.img if exist *.rom del *.rom diff --git a/Doc/ChangeLog.txt b/Doc/ChangeLog.txt index 4a4f72e5..b5dc12ec 100644 --- a/Doc/ChangeLog.txt +++ b/Doc/ChangeLog.txt @@ -1,3 +1,8 @@ +Version 3.1.1 +------------- +- WBW: Version bumped due to pervasive changes +- WBW: Preliminary support for hard disk partition support (backward compatible) + Version 3.1 ----------- - WBW: Refactored ROM Loader diff --git a/Source/Apps/Assign.asm b/Source/Apps/Assign.asm index 0bbf038e..00402cfb 100644 --- a/Source/Apps/Assign.asm +++ b/Source/Apps/Assign.asm @@ -22,7 +22,8 @@ ; 2016-04-08 [WBW] Determine key memory addresses dynamically ; 2019-08-07 [WBW] Fixed DPB selection error ; 2019-11-17 [WBW] Added preliminary CP/M 3 support -; 2019-12-24 [WBW] Fixed location of BIOS save area +; 2019-12-24 [WBW] Fixed location of BIOS save area\ +; 2020-04-29 [WBW] Updated for larger DPH (16 -> 20 bytes) ;_______________________________________________________________________________ ; ; ToDo: @@ -546,7 +547,8 @@ dph_init2: ld a,(hl) ; unit to A push bc ; save loop control push hl ; save drive map pointer - ld hl,16 ; size of a DPH structure + ;ld hl,16 ; size of a DPH structure + ld hl,20 ; size of a DPH structure call alloc ; allocate space for dph jp c,instovf ; handle overflow error push hl ; save DPH location @@ -1866,10 +1868,10 @@ stack .equ $ ; stack top ; Messages ; indent .db " ",0 -msgban1 .db "ASSIGN v1.1a for RomWBW CP/M, 24-Dec-2019",0 +msgban1 .db "ASSIGN v1.1b for RomWBW CP/M, 29-Apr-2020",0 msghb .db " (HBIOS Mode)",0 msgub .db " (UBIOS Mode)",0 -msgban2 .db "Copyright 2019, Wayne Warthen, GNU GPL v3",0 +msgban2 .db "Copyright 2020, Wayne Warthen, GNU GPL v3",0 msguse .db "Usage: ASSIGN D:[=[{D:|[]:[]}]][,...]",13,10 .db " ex. ASSIGN (display all active assignments)",13,10 .db " ASSIGN /? (display version and usage)",13,10 diff --git a/Source/Apps/Timer.asm b/Source/Apps/Timer.asm index 0d049a06..e8d21740 100644 --- a/Source/Apps/Timer.asm +++ b/Source/Apps/Timer.asm @@ -41,8 +41,11 @@ rmn .equ 1 ; intended CBIOS version - minor ; bf_sysver .equ $F1 ; BIOS: VER function bf_sysget .equ $F8 ; HBIOS: SYSGET function +bf_sysset .equ $F9 ; HBIOS: SYSGET function bf_sysgettimer .equ $D0 ; TIMER subfunction +bf_syssettimer .equ $D0 ; TIMER subfunction bf_sysgetsecs .equ $D1 ; SECONDS subfunction +bf_syssetsecs .equ $D1 ; SECONDS subfunction ; ;=============================================================================== ; Code Section @@ -106,6 +109,15 @@ process00: jr process00 ; continue looking for options ; process0: +; + ; Test of API function to set seconds value + ;ld b,bf_sysset ; HBIOS SYSGET function + ;ld c,bf_syssetsecs ; SECONDS subfunction + ;ld de,0 ; set seconds value + ;ld hl,1000 ; ... to 1000 + ;rst 08 ; call HBIOS, DE:HL := seconds value +; + ; get and print seconds value call crlf2 ; formatting ; process1: diff --git a/Source/BPBIOS/diskdefs b/Source/BPBIOS/diskdefs index 937bfcf2..dad4c46e 100644 --- a/Source/BPBIOS/diskdefs +++ b/Source/BPBIOS/diskdefs @@ -297,121 +297,158 @@ diskdef wbw_rom1024 os 2.2 end -# UNA 512KB ROM (128KB reserved, 384KB ROM Disk) +# RomWBW 720K floppy media +diskdef wbw_fd720 + seclen 512 + tracks 160 + sectrk 9 + blocksize 2048 + maxdir 128 + skew 0 + boottrk 4 + os 2.2 +end -diskdef una_rom512 +# RomWBW 1.44M floppy media +diskdef wbw_fd144 seclen 512 - tracks 12 - sectrk 64 + tracks 160 + sectrk 18 blocksize 2048 maxdir 256 skew 0 - boottrk 0 + boottrk 2 os 2.2 end -# UNA 512KB ROM (128KB reserved, 896KB ROM Disk) +# RomWBW 360K floppy media +diskdef wbw_fd360 + seclen 512 + tracks 80 + sectrk 9 + blocksize 2048 + maxdir 128 + skew 0 + boottrk 4 + os 2.2 +end -diskdef una_rom1024 +# RomWBW 1.20M floppy media +diskdef wbw_fd120 seclen 512 - tracks 28 - sectrk 64 + tracks 160 + sectrk 15 blocksize 2048 maxdir 256 skew 0 - boottrk 0 + boottrk 2 os 2.2 end -# RomWBW 8MB Hard Disk, LU 0-3 +# RomWBW 8MB Hard Disk, first 4 slices +# Legacy format, 512 dir entries, 8,320 sectors / slice diskdef wbw_hd0 seclen 512 - tracks 65 - sectrk 256 + tracks 1040 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 1 + boottrk 16 os 2.2 end diskdef wbw_hd1 seclen 512 - tracks 130 - sectrk 256 + tracks 2080 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 66 + boottrk 1056 os 2.2 end diskdef wbw_hd2 seclen 512 - tracks 195 - sectrk 256 + tracks 3120 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 131 + boottrk 2096 os 2.2 end diskdef wbw_hd3 seclen 512 - tracks 260 - sectrk 256 + tracks 4160 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 196 + boottrk 3136 os 2.2 end -# RomWBW 720K floppy media -diskdef wbw_fd720 + +# RomWBW 8MB Hard Disk +# New format, 1024 dir entries, 8,192 sectors / slice +# Pure filesystem image, no prefix +diskdef wbw_hd_new seclen 512 - tracks 160 - sectrk 9 - blocksize 2048 - maxdir 128 + tracks 1024 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 4 + boottrk 2 os 2.2 end -# RomWBW 1.44M floppy media -diskdef wbw_fd144 +# RomWBW 8MB Hard Disk, first 4 slices +# New format, 1024 dir entries, 8,192 sectors / slice +# Assumes 256 sector (16 track) hard disk prefix +diskdef wbw_hd0_new seclen 512 - tracks 160 - sectrk 18 - blocksize 2048 - maxdir 256 + tracks 1040 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 2 + boottrk 18 os 2.2 end -# RomWBW 360K floppy media -diskdef wbw_fd360 +diskdef wbw_hd1_new seclen 512 - tracks 80 - sectrk 9 - blocksize 2048 - maxdir 128 + tracks 2064 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 4 + boottrk 1042 os 2.2 end -# RomWBW 1.20M floppy media -diskdef wbw_fd120 +diskdef wbw_hd2_new seclen 512 - tracks 160 - sectrk 15 - blocksize 2048 - maxdir 256 + tracks 3112 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 2 + boottrk 2066 + os 2.2 +end + +diskdef wbw_hd3_new + seclen 512 + tracks 4136 + sectrk 16 + blocksize 4096 + maxdir 1024 + skew 0 + boottrk 3114 os 2.2 end diff --git a/Source/CBIOS/cbios.asm b/Source/CBIOS/cbios.asm index f861e737..805a43bc 100644 --- a/Source/CBIOS/cbios.asm +++ b/Source/CBIOS/cbios.asm @@ -10,8 +10,8 @@ ; 1) STACK LOCATION DURING BOOT OR WBOOT??? ; 2) REVIEW USE OF DI/EI IN INIT ; -FALSE .EQU 0 -TRUE .EQU ~FALSE +FALSE .EQU 0 +TRUE .EQU ~FALSE ; BDOS .EQU 5 ; BDOS FUNC INVOCATION VECTOR ; @@ -56,8 +56,8 @@ DEV_NUL .EQU $FF ; NUL: ; ; MEMORY LAYOUT ; -IOBYTE .EQU 3 ; LOC IN PAGE 0 OF I/O DEFINITION BYTE -CDISK .EQU 4 ; LOC IN PAGE 0 OF CURRENT DISK NUMBER 0=A,...,15=P +IOBYTE .EQU 3 ; LOC IN PAGE 0 OF I/O DEFINITION BYTE +CDISK .EQU 4 ; LOC IN PAGE 0 OF CURRENT DISK NUMBER 0=A,...,15=P ; CCP_LOC .EQU CPM_LOC CCP_SIZ .EQU $800 @@ -78,7 +78,7 @@ MEMTOP .EQU $10000 #INCLUDE "../UBIOS/ubios.inc" #ENDIF ; - .ORG CBIOS_LOC ; DEFINED IN STD.ASM + .ORG CBIOS_LOC ; DEFINED IN STD.ASM ; STACK .EQU CBIOS_END ; USE SLACK SPACE FOR STACK AS NEEDED ; @@ -112,7 +112,7 @@ WBOOTE JP WBOOT ; #1 - WARM START ; ; RomWBW CBIOS places the following stamp data into page zero ; at address $40. The address range $40-$4F is reserved by CP/M -; as a scratch area for CBIOS. This data below is copied there at +; as a scratch area for CBIOS. This data below is copied there at ; every warm start. It allows applications to identify RomWBW CBIOS. ; Additionally, it contains a pointer to additional CBIOS extension ; data (CBX) specific to RomWBW CBIOS. @@ -130,7 +130,7 @@ STPIMG: .DB 'W',~'W' ; MARKER STPSIZ .EQU $ - STPIMG ; ; The following section contains key information and addresses for the -; RomWBW CBIOS. A pointer to the start of this section is stored with +; RomWBW CBIOS. A pointer to the start of this section is stored with ; with the CBX data in page zero at $44 (see above). ; CBX: @@ -152,15 +152,15 @@ CBXSIZ .EQU $ - CBX ; IOBYTE (0003H) ; ============== ; -; Device LST: PUN: RDR: CON: -; Bit positions 7 6 5 4 3 2 1 0 +; Device LST: PUN: RDR: CON: +; Bit positions 7 6 5 4 3 2 1 0 ; -; Dec Binary +; Dec Binary ; -; 0 00 TTY: TTY: TTY: TTY: -; 1 01 CRT: PTP: PTR: CRT: -; 2 10 LPT: UP1: UR1: BAT: -; 3 11 UL1: UP2: UR2: UC1: +; 0 00 TTY: TTY: TTY: TTY: +; 1 01 CRT: PTP: PTR: CRT: +; 2 10 LPT: UP1: UR1: BAT: +; 3 11 UL1: UP2: UR2: UC1: ; ; TTY: Teletype device (slow speed console) ; CRT: Cathode ray tube device (high speed console) @@ -235,7 +235,7 @@ DEVMAP: ;================================================================================================== ; ; Disk mapping is done using a drive map table (DRVMAP) which is built -; dynamically at cold boot. See the DRV_INIT routine. This table is +; dynamically at cold boot. See the DRV_INIT routine. This table is ; made up of entries as documented below. The table is prefixed with one ; byte indicating the number of entries. The position of the entry indicates ; the drive letter, so the first entry is A:, the second entry is B:, etc. @@ -245,24 +245,24 @@ DEVMAP: ; DPH: DPH ADDRESS OF DRIVE (WORD) ; ; DRVMAP --+ -; | DRIVE A | DRIVE B | | DRIVE N | -; +-----V------+-------+-----+--------------------+ +--------------------+ -; | N | UNIT | SLICE | DPH | UNIT | SLICE | DPH | ... | UNIT | SLICE | DPH | -; +----8+-----8+------8+-+-16+-----8+------8+-+-16+ +-----8+------8+-+-16+ -; | | | -; +--------------------+ +-> [DPH] +-> [DPH] +; | DRIVE A | DRIVE B | | DRIVE N | +; +-----V------+-------+-----+--------------------+ +--------------------+ +; | N | UNIT | SLICE | DPH | UNIT | SLICE | DPH | ... | UNIT | SLICE | DPH | +; +----8+-----8+------8+-+-16+-----8+------8+-+-16+ +-----8+------8+-+-16+ +; | | | +; +--------------------+ +-> [DPH] +-> [DPH] ; | -; V-----+-------+-------+-------+--------+-----+-----+-----+ -; DPH: | XLT | 0000H | 0000H | 0000H | DIRBUF | DPB | CSV | ALV | -; +---16+-----16+-----16+-----16+------16+-+-16+-+-16+-+-16+ -; (ONE DPH PER DRIVE) | | | -; | | +----------+ -; | | | -; +----------------------+ V-------------+ V-------------+ -; | | CSV BUF | | ALV BUF | -; | +-------------+ +-------------+ -; | (CSZ BYTES) (ASZ BYTES) -; | +; V-----+-------+-------+-------+--------+-----+-----+-----+--------+ +; DPH: | XLT | 0000H | 0000H | 0000H | DIRBUF | DPB | CSV | ALV | LBAOFF | +; +---16+-----16+-----16+-----16+------16+-+-16+-+-16+-+-16+------32+ +; (ONE DPH PER DRIVE) | | | +; | | +----------+ +; | | | +; +----------------------+ V-------------+ V-------------+ +; | | CSV BUF | | ALV BUF | +; | +-------------+ +-------------+ +; | (CSZ BYTES) (ASZ BYTES) +; | ; +-----+-----+-----V-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ ; DPB: | CSZ | ASZ | BLS | SPT | BSH | BLM | EXM | DSM | DRM | AL0 | AL1 | CKS | OFF | ; +---16+---16+----8+---16+----8+----8+----8+---16+---16+----8+----8+---16+---16+ @@ -289,6 +289,7 @@ DPBMAP: .DW DPB_FD360 ; MID_FD360 .DW DPB_FD120 ; MID_FD120 .DW DPB_FD111 ; MID_FD111 + .DW DPB_HDNEW ; MID_HDNEW (1024 DIR ENTRIES) ; DPBCNT .EQU ($ - DPBMAP) / 2 ; @@ -1199,6 +1200,7 @@ DSK_GETINF1: ; ERROR RETURN DSK_SELECT: LD B,E ; SAVE E IN B FOR NOW CALL DSK_GETINF ; GET D=UNIT, E=SLICE, HL=DPH ADDRESS + CALL NZ,PANIC ; *DEBUG* RET NZ ; RETURN IF INVALID DRIVE (A=1, NZ SET, HL=0) PUSH BC ; WE NEED B LATER, SAVE ON STACK ; @@ -1209,13 +1211,15 @@ DSK_SELECT: LD (SEKUNIT),A ; SAVE UNIT LD (SEKDPH),HL ; SAVE DPH ADDRESS ; - ; UPDATE OFFSET FOR ACTIVE SLICE - ; A TRACK IS ASSUMED TO BE 16 SECTORS - ; THE OFFSET REPRESENTS THE NUMBER OF BLOCKS * 256 - ; TO USE AS THE OFFSET - LD H,65 ; H = TRACKS PER SLICE, E = SLICE NO - CALL MULT8 ; HL := H * E (TOTAL TRACK OFFSET) - LD (SEKOFF),HL ; SAVE NEW TRACK OFFSET + LD A,E ; A := SLICE + LD (SLICE),A ; SAVE IT + ; UPDATE LBAOFF FROM DPH + LD HL,(SEKDPH) + LD A,16 + CALL ADDHLA + LD DE,SEKLBA + LD BC,4 + LDIR ; ; RESTORE DE TO BC (FOR ACCESS TO DRIVE LOGIN BIT) POP BC ; GET ORIGINAL E INTO B @@ -1234,11 +1238,24 @@ DSK_SELECT: LD E,1 ; ENABLE MEDIA CHECK/DISCOVERY RST 08 ; DO IT LD A,E ; RESULTANT MEDIA ID TO ACCUM + LD (MEDID),A ; SAVE IT OR A ; SET FLAGS LD HL,0 ; ASSUME FAILURE RET Z ; BAIL OUT IF NO MEDIA ; - ; A HAS MEDIA ID, SET HL TO CORRESPONDING DPBMAP ENTRY + ; CLEAR LBA OFFSET (DWORD) + LD HL,0 ; ZERO + LD (SEKLBA),HL ; CLEAR FIRST WORD + LD (SEKLBA+2),HL ; CLEAR SECOND WORD +; + ; CHECK MBR OF PHYSICAL DISK BEING SELECTED + ; WILL UPDATE MEDID AND LBAOFF IF VALID CP/M PARTITION EXISTS + CALL DSK_MBR ; UPDATE MEDIA FROM MBR + LD HL,0 ; ASSUME FAILURE + RET NZ ; ABORT ON I/O ERROR +; + ; SET HL TO DPBMAP ENTRY CORRESPONDING TO MEDIA ID + LD A,(MEDID) ; GET MEDIA ID LD HL,DPBMAP ; HL = DPBMAP RLCA ; DPBMAP ENTRIES ARE 2 BYTES EACH CALL ADDHLA ; ADD OFFSET TO HL @@ -1249,12 +1266,22 @@ DSK_SELECT: LD D,(HL) ; DE = ADDRESS OF DESIRED DPB ; ; PLUG DPB INTO THE ACTIVE DPH - LD HL,(SEKDPH) + LD HL,(SEKDPH) ; POINT TO START OF DPH LD BC,10 ; OFFSET OF DPB IN DPH ADD HL,BC ; HL := DPH.DPB LD (HL),E ; SET LSB OF DPB IN DPH INC HL ; BUMP TO MSB LD (HL),D ; SET MSB OF DPB IN DPH +; +; ; PLUG LBA OFFSET INTO ACTIVE DPH + LD HL,(SEKDPH) ; POINT TO START OF DPH + LD BC,16 ; OFFSET OF LBA OFFSET IN DPH + ADD HL,BC ; HL := DPH.LBAOFF PTR + EX DE,HL ; DEST IS DPH.LBAOFF PTR + LD HL,SEKLBA ; SOURCE IS LBAOFF + LD BC,4 ; 4 BYTES + LDIR ; DO IT +; #ENDIF ; DSK_SELECT2: @@ -1262,6 +1289,131 @@ DSK_SELECT2: XOR A ; FLAG SUCCESS RET ; NORMAL RETURN ; +; CHECK MBR OF DISK TO SEE IF IT HAS A PARTITION TABLE. +; IF SO, LOOK FOR A CP/M PARTITION. IF FOUND, GET +; UPDATE THE PARTITION OFFSET (LBAOFF) AND UPDATE +; THE MEDIA ID (MEDID). +; +#IFDEF PLTWBW +; +DSK_MBR: + ; CHECK MEDIA TYPE, ONLY HARD DISK IS APPLICABLE + LD A,(MEDID) ; GET MEDIA ID + CP MID_HD ; HARD DISK? + JR Z,DSK_MBR1 ; IF SO, CONTINUE + XOR A ; ELSE, N/A, SIGNAL SUCCESS + RET ; AND RETURN +; +DSK_MBR1: + ; FLUSH DSKBUF TO MAKE SURE IT IS SAFE TO USE IT. + CALL BLKFLSH ; MAKE SURE DISK BUFFER IS NOT DIRTY + XOR A ; CLEAR ACCUM + LD (HSTACT),A ; CLEAR HOST BUFFER ACTIVE FLAG +; + ; READ SECTOR ZERO (MBR) + LD B,BF_DIOREAD ; READ FUNCTION + LD A,(SEKUNIT) ; GET UNIT + LD C,A ; PUT IN C + LD DE,0 ; LBA SECTOR ZERO + LD HL,0 ; ... + CALL DSK_IO2 ; DO IT + RET NZ ; ABORT ON ERROR +; + ; SWITCH TO BIOS BANK TO ACCESS DISK BUFFER + LD A,(HB_CURBNK) ; GET CUR BANK + PUSH AF ; SAVE CUR BANK + LD A,(BNKBIOS) ; BIOS BANK + CALL HB_BNKSEL ; DO IT +; + ; CHECK SIGNATURE + LD HL,(DSKBUF) ; DSKBUF ADR + LD DE,$1FE ; OFFSET TO SIGNATURE + ADD HL,DE ; POINT TO SIGNATURE + LD A,(HL) ; GET FIRST BYTE + CP $55 ; CHECK FIRST BYTE + JR NZ,DSK_MBR4 ; NO MATCH, NO PART TABLE + INC HL ; NEXT BYTE + LD A,(HL) ; GET SECOND BYTE + CP $AA ; CHECK SECOND BYTE + JR NZ,DSK_MBR4 ; NO MATCH, NO PART TABLE, ABORT +; + ; TRY TO FIND OUR ENTRY IN PART TABLE AND CAPTURE LBA OFFSET + LD B,4 ; FOUR ENTRIES IN PART TABLE + LD HL,(DSKBUF) ; DSKBUF ADR + LD DE,$1BE+4 ; OFFSET OF FIRST ENTRY PART TYPE + ADD HL,DE ; POINT TO IT +DSK_MBR2: + LD A,(HL) ; GET PART TYPE + CP $52 ; CP/M PARTITION? + JR Z,DSK_MBR3 ; COOL, GRAB THE LBA OFFSET + LD DE,16 ; PART TABLE ENTRY SIZE + ADD HL,DE ; BUMP TO NEXT ENTRY PART TYPE + DJNZ DSK_MBR2 ; LOOP THRU TABLE + JR DSK_MBR4 ; TOO BAD, NO CP/M PARTITION +; +DSK_MBR3: + ; WE HAVE LOCATED A VALID CP/M PARTITION + ; HL POINTS TO PART TYPE FIELD OF PART ENTRY + ; UPDATE MEDIA ID + LD A,MID_HDNEW ; NEW MEDIA ID + LD (MEDID),A ; SAVE IT +; + ; CAPTURE THE LBA OFFSET + LD DE,4 ; LBA IS 4 BYTES AFTER PART TYPE + ADD HL,DE ; POINT TO IT + LD DE,SEKLBA ; LOC TO STORE LBA OFFSET + LD BC,4 ; 4 BYTES (32 BITS) + LDIR ; COPY IT +; +DSK_MBR4: + ; RESTORE BANK + POP AF ; GET PREV BANK + CALL HB_BNKSEL ; SELECT IT +; +DSK_MBR5: +; + ; DIFFERENT ALGORITHM FOR NEW HD FORMAT + LD A,(MEDID) ; GET MEDIA ID + CP MID_HDNEW ; NEW FORMAT? + JR Z,DSK_MBR6 ; IF SO, GO THERE +; + ; OLD HD FORMAT, 65 TRACKS PER SLICE + LD A,(SLICE) ; GET SLICE + LD E,A ; E = SLICE NO + LD H,65 ; H = TRACKS PER SLICE + CALL MULT8 ; HL := H * E (TOTAL TRACK OFFSET) + LD DE,0 ; CLEAR HI WORD + LD B,8 ; 16 SPT, SHIFT 4 BITS + CALL RL32 ; DO IT + JR DSK_MBR7 ; DONE +; +DSK_MBR6: + ; NEW HD FORMAT, MULTIPLY SLICE BY 8MB + LD DE,0 ; CLEAR HIWORD + LD H,0 ; CLEAR HI BYTE OR LOWORD + LD A,(SLICE) ; GET SLICE + LD L,A ; PUT SLICE IN LOW BYTE + LD B,14 + CALL RL32 ; MULTIPLY BY 16384 SECTORS (8MB) +; +DSK_MBR7: + ; ADD IN LBA OFFSET + LD BC,(SEKLBA) ; LBA OFFSET LOWORD + ADD HL,BC + EX DE,HL + LD BC,(SEKLBA+2) ; LBA OFFSET HIWORD + ADC HL,BC + EX DE,HL + SET 7,D ; SET LBA ACCESS BIT + ; RESAVE IT + LD (SEKLBA),HL ; LOWORD + LD (SEKLBA+2),DE ; HIWORD + ; SUCCESSFUL FINISH + XOR A ; SUCCESS + RET ; DONE +; +#ENDIF +; ; ; DSK_STATUS: @@ -1297,7 +1449,7 @@ DSK_WRITE: ; ; #IFDEF PLTUNA - +; DSK_IO: PUSH BC LD DE,(HSTTRK) ; GET TRACK INTO HL @@ -1338,15 +1490,10 @@ DSK_IO1: RST 08 OR A ; SET FLAGS BASED ON RESULT RET - -#ELSE - -DSK_IO: ; -; TRANSLATE CP/M TRACK/SECTOR -> HBIOS TRACK/HEAD/SECTOR -; NEEDS TO HANDLE FLOPPY SEPARATE FROM HARD DISK +#ELSE ; -CHS: +DSK_IO: LD A,(HSTUNIT) ; GET UNIT LD C,A ; UNIT -> C PUSH BC ; SAVE FUNC/UNIT @@ -1356,7 +1503,7 @@ CHS: LD A,D ; DEVICE TYPE -> A AND $F0 ; ISOLATE HIGH BITS CP DIODEV_FD ; FLOPPY? - JR NZ,CHSHD ; IF NOT, DO HD CHS XLAT + JR NZ,LBA_IO ; IF NOT, DO LBA IO ; ; FLOPPY SPECIFIC TRANSLATION ASSUMES FLOPPY IS DOUBLE-SIDED AND ; USES LOW ORDER BIT OF TRACK AS HEAD VALUE @@ -1368,53 +1515,51 @@ CHS: SRL H ; SHIFT HEAD BIT OUT OF HL RR L ; ... AND INTO CARRY RL D ; CARRY BIT (HEAD) INTO D - JR CHS2 -; -; HARD DISK SPECIFIC TRANSLATION -; ASSUMES 16 HEADS PER CYLINDER AND 16 SECTORS PER TRACK + JR DSK_IO2 ; DO THE DISK I/O ; -CHSHD: - LD HL,(HSTTRK) ; GET TRACK VALUE - LD A,L ; LSB OF TRACK TO A - AND $0F ; ISOLATE HEAD IN LOW 4 BITS - LD D,A ; STUFF IT IN D +LBA_IO: + LD A,(HSTUNIT) ; GET THE UNIT VALUE + LD C,A ; PUT IT IN C + PUSH BC ; SAVE FUNC/UNIT + ; GET TRACK AND SHIFT TO MAKE ROOM FOR 4 BIT SECTOR VALUE + LD HL,(HSTTRK) ; GET TRACK + LD DE,0 ; CLEAR HIWORD + LD B,4 ; X16 (16 SPT ASSUMED) + CALL RL32 ; DO IT + ; COMBINE WITH SECTOR LD A,(HSTSEC) ; GET SECTOR - LD E,A ; STUFF IT IN E - LD A,B ; SAVE B (HBIOS FUNC) - LD B,4 ; PREPARE TO SHIFT OUT 4 BIT HEAD VALUE -CHSHD1: - SRL H ; SHIFT ONE BIT OUT - RR L ; ... OF HL - DJNZ CHSHD1 ; DO ALL 4 BITS - LD B,A ; RESTORE B (HBIOS FUNC) - ; FALL THRU TO CHS2 -; -; ALL TYPES OF TRANSLATION WIND UP HERE TO -; MAKE THE ACTUAL HBIOS CALL -; -CHS2: - PUSH DE ; SAVE HEAD/SECTOR + COULD MOVE - LD DE,(HSTOFF) ; NOW GET SLICE OFFSET | TO CHSHD, - ADD HL,DE ; ADD IT TO TRACK VALUE | NO SLICES - POP DE ; RECOVER HEAD/SECTOR + FOR FLOPPY + OR L + LD L,A + ; ADD IN LBA OFFSET FOR PARTITION AND/OR SLICE + LD BC,(HSTLBA) ; LBA OFFSET LOWORD + ADD HL,BC + EX DE,HL + LD BC,(HSTLBA+2) ; LBA OFFSET HIWORD + ADC HL,BC + EX DE,HL + SET 7,D ; MAKE SURE LBA ACCESS BIT SET + POP BC ; RESTORE FUNC/UNIT + ;JR DSK_IO2 ; DO THE DISK I/O (FALL THRU) ; ; MAKE HBIOS CALL ; HBIOS FUNC SHOULD STILL BE IN B ; UNIT SHOULD STILL BE IN C ; +DSK_IO2: PUSH BC ; SAVE INCOMING FUNCTION, DEVICE/UNIT - LD B,BF_DIOSEEK ; SETUP FOR NEW SEEK CALL + LD B,BF_DIOSEEK ; SETUP FOR NEW SEEK CALL RST 08 ; DO IT - POP BC ; RESTORE INCOMING FUNCTION, DEVICE/UNIT - RET NZ ; ABORT IF SEEK RETURNED AN ERROR W/ ERROR IN A - LD HL,(DSKBUF) ; GET BUFFER ADDRESS + POP BC ; RESTORE INCOMING FUNCTION, DEVICE/UNIT + RET NZ ; ABORT IF SEEK RETURNED AN ERROR W/ ERROR IN A + LD HL,(DSKBUF) ; GET BUFFER ADDRESS LD A,(BNKBIOS) ; GET BIOS BANK LD D,A ; TRANSFER TO/FROM BIOS BANK - LD E,1 ; TRANSFER ONE SECTOR + LD E,1 ; TRANSFER ONE SECTOR + ;CALL PC_ASTERISK ; *DEBUG* RST 08 ; DO IT OR A ; SET FLAGS RET ; DONE - +; #ENDIF ; ;================================================================================================== @@ -1501,12 +1646,14 @@ STR_SEC .DB " SEC=$" ; DATA ;================================================================================================== ; -;STR_READONLY .DB "\r\nCBIOS Err: Read Only Drive$" -;STR_STALE .DB "\r\nCBIOS Err: Stale Drive$" +;STR_READONLY .DB "\r\nCBIOS Err: Read Only Drive$" +;STR_STALE .DB "\r\nCBIOS Err: Stale Drive$" ; -SECADR .DW 0 ; ADDRESS OF SECTOR IN ROM/RAM PAGE +;SECADR .DW 0 ; ADDRESS OF SECTOR IN ROM/RAM PAGE DEFDRIVE .DB 0 ; DEFAULT DRIVE CCPBUF .DW 0 ; ADDRESS OF CCP BUF IN BIOS BANK +MEDID .DB 0 ; TEMP STORAGE FOR MEDIA ID +SLICE .DB 0 ; CURRENT SLICE ; #IFDEF PLTWBW BNKBIOS .DB 0 ; BIOS BANK ID @@ -1521,21 +1668,22 @@ BNKUSER .DW 0 ; USER BANK ID ; DOS DISK VARIABLES ; DSKOP .DB 0 ; DISK OPERATION (DOP_READ/DOP_WRITE) -WRTYPE .DB 0 ; WRITE TYPE (0=NORMAL, 1=DIR (FORCE), 2=FIRST RECORD OF BLOCK) -DMAADR .DW 0 ; DIRECT MEMORY ADDRESS +WRTYPE .DB 0 ; WRITE TYPE (0=NORMAL, 1=DIR (FORCE), 2=FIRST RECORD OF BLOCK) +DMAADR .DW 0 ; DIRECT MEMORY ADDRESS HSTWRT .DB 0 ; TRUE = BUFFER IS DIRTY DSKBUF .DW 0 ; ADDRESS OF PHYSICAL SECTOR BUFFER ; ; LOGICAL DISK I/O REQUEST PENDING ; SEK: -SEKDSK .DB 0 ; DISK NUMBER 0-15 -SEKTRK .DW 0 ; TWO BYTES FOR TRACK # (LOGICAL) -SEKSEC .DW 0 ; TWO BYTES FOR SECTOR # (LOGICAL) -SEKUNIT .DB 0 ; DISK UNIT +SEKDSK .DB 0 ; DISK NUMBER 0-15 +SEKTRK .DW 0 ; TWO BYTES FOR TRACK # (LOGICAL) +SEKSEC .DW 0 ; TWO BYTES FOR SECTOR # (LOGICAL) +SEKUNIT .DB 0 ; DISK UNIT SEKDPH .DW 0 ; ADDRESS OF ACTIVE (SELECTED) DPH SEKOFF .DW 0 ; TRACK OFFSET IN EFFECT FOR SLICE SEKACT .DB TRUE ; ALWAYS TRUE! +SEKLBA .FILL 4,0 ; LBA OFFSET ; ; RESULT OF CPM TO PHYSICAL TRANSLATION ; @@ -1547,6 +1695,7 @@ XLTUNIT .DB 0 XLTDPH .DW 0 XLTOFF .DW 0 XLTACT .DB TRUE ; ALWAYS TRUE! +XLTLBA .FILL 4,0 ; LBA OFFSET ; XLTSIZ .EQU $ - XLT ; @@ -1560,13 +1709,14 @@ HSTUNIT .DB 0 ; DISK UNIT IN BUFFER HSTDPH .DW 0 ; CURRENT DPH ADDRESS HSTOFF .DW 0 ; TRACK OFFSET IN EFFECT FOR SLICE HSTACT .DB 0 ; TRUE = BUFFER HAS VALID DATA +HSTLBA .FILL 4,0 ; LBA OFFSET ; ; SEQUENTIAL WRITE TRACKING FOR (UNA)LLOCATED BLOCK ; UNA: -UNADSK .DB 0 ; DISK NUMBER 0-15 -UNATRK .DW 0 ; TWO BYTES FOR TRACK # (LOGICAL) -UNASEC .DW 0 ; TWO BYTES FOR SECTOR # (LOGICAL) +UNADSK .DB 0 ; DISK NUMBER 0-15 +UNATRK .DW 0 ; TWO BYTES FOR TRACK # (LOGICAL) +UNASEC .DW 0 ; TWO BYTES FOR SECTOR # (LOGICAL) ; UNASIZ .EQU $ - UNA ; @@ -1595,13 +1745,13 @@ ALS_HD .EQU 256 ; ALS: BLKS / 8 = 2048 / 8 = 256 (ROUNDED UP) ; BLS BSH BLM EXM (DSM<256) EXM (DSM>255) ; ---------- --- --- ------------- ------------- ; 1,024 3 7 0 N/A -; 2,048 4 15 1 0 -; 4,096 5 31 3 1 -; 8,192 6 63 7 3 -; 16,384 7 127 15 7 +; 2,048 4 15 1 0 +; 4,096 5 31 3 1 +; 8,192 6 63 7 3 +; 16,384 7 127 15 7 ; -; AL0/1: EACH BIT SET ALLOCATES A BLOCK OF DIR ENTRIES. EACH DIR ENTRY -; IS 32 BYTES. BIT COUNT = (((DRM + 1) * 32) / BLS) +; AL0/1: EACH BIT SET ALLOCATES A BLOCK OF DIR ENTRIES. EACH DIR ENTRY +; IS 32 BYTES. BIT COUNT = (((DRM + 1) * 32) / BLS) ; ; CKS = (DIR ENT / 4), ZERO FOR NON-REMOVABLE MEDIA ; @@ -1623,16 +1773,16 @@ ALS_HD .EQU 256 ; ALS: BLKS / 8 = 2048 / 8 = 256 (ROUNDED UP) .DW ALS_ROM ; ALS: BLKS / 8 .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) DPB_ROM: - .DW 64 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK + .DW 64 ; SPT: SECTORS PER TRACK + .DB 4 ; BSH: BLOCK SHIFT FACTOR + .DB 15 ; BLM: BLOCK MASK .DB 1 ; EXM: (BLKS <= 256) ? 1 : 0 .DW 192 - 1 ; DSM: TOTAL STORAGE IN BLOCKS - 1 - .DW 255 ; DRM: DIR ENTRIES - 1 = 255 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 0 ; CKS: ZERO FOR NON-REMOVABLE MEDIA - .DW 0 ; OFF: ROM DISK HAS NO SYSTEM AREA + .DW 255 ; DRM: DIR ENTRIES - 1 = 255 + .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 0 ; CKS: ZERO FOR NON-REMOVABLE MEDIA + .DW 0 ; OFF: ROM DISK HAS NO SYSTEM AREA ;__________________________________________________________________________________________________ ; ; RAM DISK: 64 SECS/TRK, 128 BYTES/SEC @@ -1650,16 +1800,16 @@ DPB_ROM: .DW ALS_RAM ; ALS: BLKS / 8 .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) DPB_RAM: - .DW 64 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK + .DW 64 ; SPT: SECTORS PER TRACK + .DB 4 ; BSH: BLOCK SHIFT FACTOR + .DB 15 ; BLM: BLOCK MASK .DB 1 ; EXM: (BLKS <= 256) ? 1 : 0 .DW 192 - 1 ; DSM: TOTAL STORAGE IN BLOCKS - 1 - .DW 255 ; DRM: DIR ENTRIES - 1 = 255 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 0 ; CKS: ZERO FOR NON-REMOVABLE MEDIA - .DW 0 ; OFF: RESERVED TRACKS = 0 TRK + .DW 255 ; DRM: DIR ENTRIES - 1 = 255 + .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 0 ; CKS: ZERO FOR NON-REMOVABLE MEDIA + .DW 0 ; OFF: RESERVED TRACKS = 0 TRK ;__________________________________________________________________________________________________ ; ; 4MB RAM FLOPPY DRIVE, 32 TRKS, 1024 SECS/TRK, 128 BYTES/SEC @@ -1669,16 +1819,16 @@ DPB_RAM: .DW ALS_HD .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) DPB_RF: - .DW 64 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK - .DB 0 ; EXM: EXTENT MASK - .DW 2047 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = (4MB / 2K BLS) - 1 = 2047 - .DW 511 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 - .DB 11111111B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 0 ; CKS: ZERO FOR NON-REMOVABLE MEDIA - .DW 0 ; OFF: RESERVED TRACKS = 0 TRK + .DW 64 ; SPT: SECTORS PER TRACK + .DB 4 ; BSH: BLOCK SHIFT FACTOR + .DB 15 ; BLM: BLOCK MASK + .DB 0 ; EXM: EXTENT MASK + .DW 2047 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = (4MB / 2K BLS) - 1 = 2047 + .DW 511 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 + .DB 11111111B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 0 ; CKS: ZERO FOR NON-REMOVABLE MEDIA + .DW 0 ; OFF: RESERVED TRACKS = 0 TRK ;__________________________________________________________________________________________________ ; ; GENERIC HARD DISK DRIVE (8MB DATA SPACE + 128K RESERVED SPACE) @@ -1690,16 +1840,33 @@ DPB_RF: .DW ALS_HD .DB (4096 / 128) ; RECORDS PER BLOCK (BLS / 128) DPB_HD: - .DW 64 ; SPT: SECTORS PER TRACK - .DB 5 ; BSH: BLOCK SHIFT FACTOR - .DB 31 ; BLM: BLOCK MASK - .DB 1 ; EXM: EXTENT MASK - .DW 2047 ; DSM: TOTAL STORAGE IN BLOCKS - 1 = (8MB / 4K BLS) - 1 = 2047 - .DW 511 ; DRM: DIR ENTRIES - 1 = 512 - 1 = 511 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 0 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 - .DW 16 ; OFF: RESERVED TRACKS = 16 TRKS * (16 TRKS * 16 HEADS * 16 SECS * 512 BYTES) = 128K + .DW 64 ; SPT: SECTORS PER TRACK + .DB 5 ; BSH: BLOCK SHIFT FACTOR + .DB 31 ; BLM: BLOCK MASK + .DB 1 ; EXM: EXTENT MASK + .DW 2047 ; DSM: TOTAL STORAGE IN BLOCKS - 1 = (8MB / 4K BLS) - 1 = 2047 + .DW 512 - 1 ; DRM: DIR ENTRIES - 1 + .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 0 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 + .DW 16 ; OFF: RESERVED TRACKS +; +; BLOCKSIZE (BLS) = 4K, DIRECTORY ENTRIES = 1024 +; + .DW CKS_HD + .DW ALS_HD + .DB (4096 / 128) ; RECORDS PER BLOCK (BLS / 128) +DPB_HDNEW: + .DW 64 ; SPT: SECTORS PER TRACK + .DB 5 ; BSH: BLOCK SHIFT FACTOR + .DB 31 ; BLM: BLOCK MASK + .DB 1 ; EXM: EXTENT MASK + .DW 2048 - 1 - 4 ; DSM: STORAGE BLOCKS - 1 - RES TRKS + .DW 1024 - 1 ; DRM: DIR ENTRIES - 1 + .DB 11111111B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 0 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 + .DW 2 ; OFF: RESERVED TRACKS ;__________________________________________________________________________________________________ ; ; IBM 720KB 3.5" FLOPPY DRIVE, 80 TRKS, 36 SECS/TRK, 512 BYTES/SEC @@ -1709,16 +1876,16 @@ DPB_HD: .DW ALS_FD .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) DPB_FD720: - .DW 36 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK - .DB 0 ; EXM: EXTENT MASK - .DW 350 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((720K - 18K OFF) / 2K BLS) - 1 = 350 - .DW 127 ; DRM: DIR ENTRIES - 1 = 128 - 1 = 127 - .DB 11000000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 32 ; CKS: DIRECTORY CHECK VECTOR SIZE = 128 / 4 - .DW 4 ; OFF: RESERVED TRACKS = 4 TRKS * (512 B/SEC * 36 SEC/TRK) = 18K + .DW 36 ; SPT: SECTORS PER TRACK + .DB 4 ; BSH: BLOCK SHIFT FACTOR + .DB 15 ; BLM: BLOCK MASK + .DB 0 ; EXM: EXTENT MASK + .DW 350 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((720K - 18K OFF) / 2K BLS) - 1 = 350 + .DW 127 ; DRM: DIR ENTRIES - 1 = 128 - 1 = 127 + .DB 11000000B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 32 ; CKS: DIRECTORY CHECK VECTOR SIZE = 128 / 4 + .DW 4 ; OFF: RESERVED TRACKS = 4 TRKS * (512 B/SEC * 36 SEC/TRK) = 18K ;__________________________________________________________________________________________________ ; ; IBM 1.44MB 3.5" FLOPPY DRIVE, 80 TRKS, 72 SECS/TRK, 512 BYTES/SEC @@ -1728,16 +1895,16 @@ DPB_FD720: .DW ALS_FD .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) DPB_FD144: - .DW 72 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK - .DB 0 ; EXM: EXTENT MASK - .DW 710 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,440K - 18K OFF) / 2K BLS) - 1 = 710 - .DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 - .DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 72 SEC/TRK) = 18K + .DW 72 ; SPT: SECTORS PER TRACK + .DB 4 ; BSH: BLOCK SHIFT FACTOR + .DB 15 ; BLM: BLOCK MASK + .DB 0 ; EXM: EXTENT MASK + .DW 710 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,440K - 18K OFF) / 2K BLS) - 1 = 710 + .DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 + .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 + .DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 72 SEC/TRK) = 18K ;__________________________________________________________________________________________________ ; ; IBM 360KB 5.25" FLOPPY DRIVE, 40 TRKS, 9 SECS/TRK, 512 BYTES/SEC @@ -1747,16 +1914,16 @@ DPB_FD144: .DW ALS_FD .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) DPB_FD360: - .DW 36 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK - .DB 1 ; EXM: EXTENT MASK - .DW 170 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((360K - 18K OFF) / 2K BLS) - 1 = 170 - .DW 127 ; DRM: DIR ENTRIES - 1 = 128 - 1 = 127 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 32 ; CKS: DIRECTORY CHECK VECTOR SIZE = 128 / 4 - .DW 4 ; OFF: RESERVED TRACKS = 4 TRKS * (512 B/SEC * 36 SEC/TRK) = 18K + .DW 36 ; SPT: SECTORS PER TRACK + .DB 4 ; BSH: BLOCK SHIFT FACTOR + .DB 15 ; BLM: BLOCK MASK + .DB 1 ; EXM: EXTENT MASK + .DW 170 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((360K - 18K OFF) / 2K BLS) - 1 = 170 + .DW 127 ; DRM: DIR ENTRIES - 1 = 128 - 1 = 127 + .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 32 ; CKS: DIRECTORY CHECK VECTOR SIZE = 128 / 4 + .DW 4 ; OFF: RESERVED TRACKS = 4 TRKS * (512 B/SEC * 36 SEC/TRK) = 18K ;__________________________________________________________________________________________________ ; ; IBM 1.20MB 5.25" FLOPPY DRIVE, 80 TRKS, 15 SECS/TRK, 512 BYTES/SEC @@ -1766,16 +1933,16 @@ DPB_FD360: .DW ALS_FD .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) DPB_FD120: - .DW 60 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK - .DB 0 ; EXM: EXTENT MASK - .DW 591 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,200K - 15K OFF) / 2K BLS) - 1 = 591 - .DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 - .DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 60 SEC/TRK) = 15K + .DW 60 ; SPT: SECTORS PER TRACK + .DB 4 ; BSH: BLOCK SHIFT FACTOR + .DB 15 ; BLM: BLOCK MASK + .DB 0 ; EXM: EXTENT MASK + .DW 591 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,200K - 15K OFF) / 2K BLS) - 1 = 591 + .DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 + .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 + .DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 60 SEC/TRK) = 15K ;__________________________________________________________________________________________________ ; ; IBM 1.11MB 8" FLOPPY DRIVE, 77 TRKS, 15 SECS/TRK, 512 BYTES/SEC @@ -1785,16 +1952,16 @@ DPB_FD120: .DW ALS_FD .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) DPB_FD111: - .DW 60 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK - .DB 0 ; EXM: EXTENT MASK - .DW 569 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,155K - 15K OFF) / 2K BLS) - 1 = 569 - .DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 - .DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 60 SEC/TRK) = 15K + .DW 60 ; SPT: SECTORS PER TRACK + .DB 4 ; BSH: BLOCK SHIFT FACTOR + .DB 15 ; BLM: BLOCK MASK + .DB 0 ; EXM: EXTENT MASK + .DW 569 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,155K - 15K OFF) / 2K BLS) - 1 = 569 + .DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 + .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE + .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE + .DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 + .DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 60 SEC/TRK) = 15K ; #IFDEF PLTUNA SECBUF .FILL 512,0 ; PHYSICAL DISK SECTOR BUFFER @@ -2086,7 +2253,7 @@ DEV_INIT0: ;POP BC ; RESTORE LOOP CONTROL ;LD A,C ; UNIT INDEX TO ACCUM ;;CALL C,JPHL ; DO IT IF DEVICE TYPE < VDU - + LD A,(HCB + HCB_CONDEV) ; CURRENT CONSOLE UNIT CP C ; IS CURRENT CONSOLE? LD A,C ; UNIT INDEX TO ACCUM @@ -2650,7 +2817,8 @@ DPH_INIT: LD H,0 ; ... INTO HL ADD HL,HL ; MULTIPLY ADD HL,HL ; ... BY SIZE - ADD HL,HL ; ... OF DPH (16) + CALL ADDHLA ; ... + ADD HL,HL ; ... OF DPH (20) ADD HL,HL ; ... FOR TOTAL SIZE CALL ALLOC ; ALLOCATE THE SPACE CALL C,PANIC ; SHOULD NEVER ERROR @@ -2707,7 +2875,8 @@ DPH_INIT2: LD (HL),D ; ... DRIVE MAP INC HL ; AND BUMP TO START OF NEXT ENTRY ; UPDATE DPH ALLOCATION TOP - LD A,16 ; SIZE OF A DPH ENTRY + ;LD A,16 ; SIZE OF A DPH ENTRY + LD A,20 ; SIZE OF A DPH ENTRY EX DE,HL ; HL := DPH POINTER CALL ADDHLA ; CALC NEW DPHTOP LD (DPHTOP),HL ; SAVE IT @@ -3011,7 +3180,7 @@ CMD .DB CMDLEN - 2 CMDLEN .EQU $ - CMD ; FCB_SUB .DB '?' ; DRIVE CODE, 0 = CURRENT DRIVE - .DB "SUBMIT " ; FILE NAME, 8 CHARS + .DB "SUBMIT " ; FILE NAME, 8 CHARS .DB "COM" ; FILE TYPE, 3 CHARS .FILL 36-($-FCB_SUB),0 ; ZERO FILL REMAINDER OF FCB ; @@ -3023,7 +3192,7 @@ FCB_PRO .DB '?' ; DRIVE CODE, 0 = CURRENT DRIVE STR_BANNER .DB "CBIOS v", BIOSVER, " [", PLTSTR, "]$" STR_INITRAMDISK .DB "Formatting RAMDISK...$" STR_LDR2 .DB "\r\n" -STR_LDR .DB "\r\n $" +STR_LDR .DB "\r\n $" STR_DPHINIT .DB "Configuring Drives...$" STR_HEAPOVF .DB " *** Insufficient Memory ***$" STR_INVMED .DB " *** Invalid Device ID ***$" diff --git a/Source/CBIOS/util.asm b/Source/CBIOS/util.asm index 023688ed..1d32990e 100644 --- a/Source/CBIOS/util.asm +++ b/Source/CBIOS/util.asm @@ -430,3 +430,15 @@ PRTHEXBUF1: INC DE DJNZ PRTHEXBUF1 RET +; +; LEFT SHIFT DE:HL BY B BITS (B > 0) +; +RL32: + OR A ; CLEAR CARRY + RL L + RL H + RL E + RL D + DJNZ RL32 + RET + diff --git a/Source/CPM3/biosldr.z80 b/Source/CPM3/biosldr.z80 index 9fc960d3..1af6947d 100644 --- a/Source/CPM3/biosldr.z80 +++ b/Source/CPM3/biosldr.z80 @@ -51,109 +51,211 @@ jp 0 ; reserved for future expansion jp 0 ; reserved for future expansion -boot: - - if cmdline +mbrsec equ dtabuf +boot: + ; The main module (cpmldr.asm) does not expect the + ; boot call to use much stack. We use our own during + ; this routine to avoid issues. ld (stksav),sp ld sp,stack -boot1: - ld de,msgunit - call writestr - call cin - push af - call cout - pop af - - sub '0' - ld (unit),a - jr c,selerr - - ld bc,0F810h ; HBIOS, get disk unit count - call 0FFF0h ; do it, E := disk unit count - ld a,(unit) ; get unit num back - cp e ; compare to entry - jr nc,selerr ; loop if too high + ; Do the real work + call boot0 - ld de,msgslc - call writestr - call cin - push af - call cout - pop af - - sub '0' - ld (slice),a - jr c,selerr - cp 10 - jr nc,selerr + ; Restore original stack and return + ld sp,(stksav) + ret + +boot0: + + if cmdline - jr boot2 +boot1: + ; Get disk unit from user + ld de,msgunit ; disk unit prompt + call writestr ; display on console + call cin ; get a character + push af ; save it + call cout ; echo character + pop af ; restore it + sub '0' ; convert to binary + ld (unit),a ; save it + jr c,selerr ; loop if below 0 entered + ld bc,0F810h ; HBIOS, get disk unit count + call 0FFF0h ; do it, E := disk unit count + ld a,(unit) ; get unit num back + cp e ; compare to entry + jr nc,selerr ; loop if too high + + ; Get disk slice from user + ld de,msgslc ; slice prompt + call writestr ; display on console + call cin ; get a character + push af ; save it + call cout ; echo it + pop af ; restore it + sub '0' ; convert to binary + ld (slice),a ; save it + jr c,selerr ; loop if below 0 entered + cp 10 ; check for over 9 + jr nc,selerr ; loop if over 9 + ld de,crlf ; linefeed + call writestr ; ... to console + jr boot2 ; boot w/ unit & slice selerr: - ld de,msginv - call writestr - jr boot1 + ; Display invalid entry message and restart + ld de,msginv ; error message + call writestr ; display on console + jr boot1 ; loop boot2: - ld de,crlf - call writestr + ; Record unit & slice w/ HBIOS + ld bc,0F9E0h ; HBIOS func: set boot info + ld a,(unit) ; get unit + ld d,a ; put in D + ld a,(slice) ; get slice + ld e,a ; put in E + ld l,0 ; Bank is always zero + call 0FFF0h ; do it - ld sp,(stksav) - - ld bc,0F9E0h ; HBIOS func: set boot info - ld a,(unit) ; get unit - ld d,a ; put in D - ld a,(slice) ; get slice - ld e,a ; put in E - ld l,0 ; Bank is always zero - call 0FFF0h ; do it - else - - ld bc,0F8E0h ; HBIOS func: get boot info - call 0FFF0h ; do it, D := boot unit, E: := slice - ld a,d ; move unit to A - ld (unit),a ; save it - ld a,e ; move slice to A - ld (slice),a ; save it + + ; Get unit & slice from HBIOS + ld bc,0F8E0h ; HBIOS func: get boot info + call 0FFF0h ; do it, D := boot unit, E: := slice + ld a,d ; move unit to A + ld (unit),a ; save it + ld a,e ; move slice to A + ld (slice),a ; save it endif - ld a,(unit) ; Get boot unit - ld c,a ; put in C - ld b,18h ; HBIOS Media function - ld e,1 ; Enable media check/discovery - call 0FFF0H ; HBIOS call - ld a,e ; Resultant media id to accum - or a ; Set flags - ;halt - ; - ; !!! Need to do something on error !!! - ; - ret z ; Bail out on error - + ; Check that drive actually exists + ld bc,0F810h ; HBIOS func: get disk count + call 0FFF0h ; do it, E=disk count + ld a,(unit) ; get boot disk unit + cp e ; compare to count + jp nc,err_nodisk ; handle no disk err + + ; Sense media to determine media format + ld a,(unit) ; Get boot unit + ld c,a ; put in C + ld b,18h ; HBIOS Media function + ld e,1 ; Enable media check/discovery + call 0FFF0H ; HBIOS call + jp nz,err_diskio ; handle error + ld a,e ; resultant media id to accum + ld (medid),a ; save media id + or a ; set flags, 0 is no media + jp z,err_diskio ; handle no media error + + ; Initialize slice start LBA & sectors per slice + ld hl,0 ; assume slice starts + ld (lba),hl ; ... at LBA offset + ld (lba+2),hl ; ... of zero + ld hl,16640 ; assume legacy value for + ld (sps),hl ; ... sectors per slice + + ; If not hard disk, skip partition & slice stuff + ld a,(medid) ; get media id + cp 4 ; hard disk? + jr nz,boot9 ; if not, jump ahead + + ; Read MBR + ld de,8000h ; LBA address zero + ld hl,0 ; ... to read first sector + ld bc,mbrsec ; read into MBR buffer + ld (dma),bc ; save + ld b,1 ; one sector + ld a,(unit) ; get bootunit + ld c,a ; put in C + call diskread ; do it, no return on err + + ; Check signature + ld hl,(mbrsec+1FEh) ; get signature + ld a,l ; first byte + cp 055h ; should be $55 + jr nz,boot5 ; if not, no part table + ld a,h ; second byte + cp 0AAh ; should be $AA + jr nz,boot5 ; if not, no part table + + ; Search part table for CP/M entry (type 0x52) + ld b,4 ; four entries in part table + ld hl,mbrsec+1BEh+4 ; offset of first part type +boot3: + ld a,(hl) ; get part type + cp 52h ; CP/M partition? + jr z,boot4 ; cool, grab the LBA offset + ld de,16 ; part table entry size + add hl,de ; bump to next part type + djnz boot3 ; loop thru table + jr boot5 ; too bad, no CP/M partition + +boot4: + ; Capture the starting LBA of the CP/M partition we found + ld de,4 ; LBA is 4 bytes after part type + add hl,de ; point to it + ld de,lba ; loc to store lba offset + ld bc,4 ; 4 bytes (32 bits) + ldir ; copy it + + ; For now, it is implied that a slice within a partition + ; table will be in the "new" disk format. So, we now + ; adjust the sectors per slice and media id. + + ; Use new slice format sectors per slice value + ld hl,16384 ; new sectors per slice + ld (sps),hl ; save it + + ; Update media id for new hard disk format + ld a,10 ; new media id + ld (medid),a ; save it + +boot5: + ; Adjust LBA offset based on target slice + ld a,(slice) ; get boot slice, A is loop cnt + ld hl,(lba) ; set DE:HL + ld de,(lba+2) ; ... to starting LBA + ld bc,(sps) ; sectors per slice +boot6: + or a ; set flags to check loop cntr + jr z,boot8 ; done if counter exhausted + add hl,bc ; add one slice to low word + jr nc,boot7 ; check for carry + inc de ; if so, bump high word +boot7: + dec a ; dec loop downcounter + jr boot6 ; and loop +boot8: + ld (lba),hl ; save new lba, low word + ld (lba+2),de ; save new lba, high word + +boot9: + ; Locate DPB corresponding to media id ld hl,dpb$start - dpb$sz ld de,dpb$sz - ld b,a ; loop count -dsk$login1: - add hl,de ; next dpb - djnz dsk$login1 ; loop as needed - - ; hl is ptr to desired dpb - ld de,dph0 ; load DPH pointer - ex de,hl ; de = DPB adr, hl = DPH adr - push de ; save DPB adr - ld de,12 ; offset of DPB in DPH - add hl,de ; hl = adr of DPB field in DPH - pop de ; recover DPB adr - ld (hl),e ; update LSB - inc hl - ld (hl),d ; udpate MSB + ld a,(medid) ; get media id + ld b,a ; to loop count +boot10: + add hl,de ; next dpb + djnz boot10 ; loop as needed + + ; Stuff DPB ptr (HL) into DPH + ld de,dph0 ; load DPH pointer + ex de,hl ; de = DPB adr, hl = DPH adr + push de ; save DPB adr + ld de,12 ; offset of DPB in DPH + add hl,de ; hl = adr of DPB field in DPH + pop de ; recover DPB adr + ld (hl),e ; update LSB + inc hl ; point to MSB + ld (hl),d ; update MSB + + ret ; done - ret - wboot: ld a,81H halt @@ -162,15 +264,14 @@ const: ld a,82H halt conin: - ld bc,0080H ; unit 80h (console), func 0 = CIN - call 0FFF0H - + ld bc,0080h ; unit 80h (console), func 0 = CIN + call 0FFF0h ; do it + ld a,e ; put in C + ret ; done conout: - ld e,c ; output character in E - ld bc,0180H ; unit 80h (console), func 1 = COUT - ;rst 08 ; do it - call 0FFF0H - ret ; return + ld e,c ; output character in E + ld bc,0180h ; unit 80h (console), func 1 = COUT + jp 0FFF0h list: ld a,85H halt @@ -197,61 +298,100 @@ setsec: setdma: ld (dma),bc ret + read: - ld a,(unit) ; get unit - ld c,a ; BIOS Disk Unit in C - ld b,12H ; HBIOS SEEK function - push bc ; save it - ;push de ; save XDPH pointer - ld b,17h ; HBIOS DEVICE function - rst 08 ; Do it, D=device type - ld a,d ; put in accum - and 0F0h ; isolate high bits - ld b,1 ; assume it is floppy, 1 head bit - ld c,01h ; 1 bit head mask - cp 10h ; floppy? - jr z,seek0 ; yup, skip ahead - ld b,4 ; must be hard disk, 4 head bits - ld c,0Fh ; 4 bit head mask -seek0: - ;pop de ; recover XDPH pointer - push bc ; save bc - ld a,(slice) ; get slice - ld e,a ; slice to E - ld h,65 ; number of tracks per slice - call mult8 ; HL now has track offset for slice - pop bc ; recover bc - push hl ; save track offset for now - ld hl,(trk) ; get track value - ld a,l ; lsb of track to a - and c ; apply mask - ld d,a ; save in d -seek1: - srl h ; shift one bit out - rr l ; ... of hl - djnz seek1 ; do all bits - ld a,(sect) ; get sector - ld e,a ; stuff it in e - ex de,hl ; de=track, hl=head/sect - ex (sp),hl ; save head/sect, hl = offset - add hl,de ; hl has final track value - pop de ; recover head/sect to de - pop bc ; recover function & unit - ;rst 08 ; perform seek - call 0FFF0H - - ; Read Sector - ld b,13h ; HBIOS read - ld a,(unit) ; get boot unit - ld c,a ; put in C - ld hl,(dma) ; dma address - ld a,(0FFE0H) ; current bank - ld d,a ; ... to D - ld e,1 ; 1 sector - ;rst 08 - call 0FFF0H + ; Check device type + ld a,(unit) ; get unit + ld c,a ; BIOS Disk Unit in C + ld b,17h ; HBIOS DEVICE function + rst 08 ; Do it, D=device type + ld a,d ; put in accum + and 0F0h ; isolate high bits + cp 10h ; floppy? + jr nz,read2 ; if not, do LBA i/o - ret + ; Floppy I/O + ld de,(sect) ; sector -> de, head(d) becomes zero + ld hl,(trk) ; track -> hl (low bit has head) + srl h ; shift head bit out of hl + rr l ; ... and into carry + rl d ; carry bit (head) into d + jr read3 ; do the disk i/o + +; ; *** Simplify this to get rid of slice!!! *** +; ld b,1 ; assume it is floppy, 1 head bit +; ld c,01h ; 1 bit head mask +; push bc ; save bc +; ld a,(slice) ; get slice +; ld e,a ; slice to E +; ld h,65 ; number of tracks per slice +; call mult8 ; HL now has track offset for slice +; pop bc ; recover bc +; push hl ; save track offset for now +; ld hl,(trk) ; get track value +; ld a,l ; lsb of track to a +; and c ; apply mask +; ld d,a ; save in d +;read1: +; srl h ; shift one bit out +; rr l ; ... of hl +; djnz read1 ; do all bits +; ld a,(sect) ; get sector +; ld e,a ; stuff it in e +; ex de,hl ; DE=track, HL=head/sect +; ex (sp),hl ; save head/sect, HL = offset +; add hl,de ; HL has final track value +; pop de ; recover head/sect to de +; jr read3 + + ; LBA I/O +read2: + ld hl,(trk) ; get track + ld de,0 ; clear hiword + ld b,4 ; x16 (16 spt assumed) + call rl32 ; do it + ; combine with sector + ld a,(sect) ; get sector + or l ; combine + ld l,a ; and back to L + ; add in lba offset + ld bc,(lba) ; lba offset loword + add hl,bc ; add to cur loword + ex de,hl ; swap + ld bc,(lba+2) ; lba offset hiword + adc hl,bc ; add w/ carry to cur hiword + ex de,hl ; swap back + set 7,d ; set lba access bit + +read3: + ; DE:HL has sector address to read (LBA or CHS) + ld a,(unit) ; get disk unit + ld c,a ; put in C + ld b,1 ; read 1 sector + jr diskread ; read sector and return + +diskread: + ; Read disk sector(s) + ; DE:HL is LBA, B is sector count, C is disk unit + + ; Seek to requested sector in DE:HL + push bc ; save unit & count + ld b,012h ; HBIOS func: seek + call 0FFF0h ; do it + pop bc ; recover unit & count + jp nz,err_diskio ; handle error + + ; Read sector(s) into buffer + ld e,b ; transfer count + ld b,013h ; HBIOS func: disk read + ld hl,(dma) ; read into info sec buffer + ld a,(0FFE0h) ; get current bank + ld d,a ; put in D + call 0FFF0h ; do it + jp nz,err_diskio ; handle error + xor a ; signal success + ret ; and done + write: ld a,8EH halt @@ -291,10 +431,11 @@ flush: halt move: - ex de,hl ; we are passed source in DE and dest in HL - ldir ; use Z80 block move instruction - ex de,hl ; need next addresses in same regs - ret + ; On input, DE=src, HL=dest + ex de,hl ; swap HL/DE for LDIR + ldir ; Z80 block move + ex de,hl ; swap back (required!) + ret ; done time: ld a,9AH halt @@ -307,22 +448,21 @@ setbnk: xmove: ld a,9DH halt - + cin: - ; input character from console via hbios - ld c,080H ; console unit to c - ld b,00H ; hbios func: input char - call 0FFF0H ; hbios reads character - ld a,e ; move character to a for return - ret + ; Input character from console via HBIOS + ld c,080H ; console unit to C + ld b,00H ; HBIOS func: input char + call 0FFF0H ; HBIOS reads character + ld a,e ; To A for return + ret ; done cout: - ; output character to console via hbios - ld e,a ; output char to e - ld c,080H ; console unit to c - ld b,01H ; hbios func: output char - call 0FFF0H ; hbios outputs character - ret + ; Output character to console via HBIOS + ld e,a ; output char to E + ld c,080H ; console unit to C + ld b,01H ; HBIOS func: output char + jp 0FFF0H ; output & return writestr: push af @@ -339,12 +479,8 @@ writestr2: pop af ret -; -; multiply 8-bit values -; in: multiply h by e -; out: hl = result, e = 0, b = 0 -; mult8: + ; Multiply: H := H * E ld d,0 ld l,d ld b,8 @@ -356,6 +492,46 @@ mult8_noadd: djnz mult8_loop ret +rl32: + ; Left shift DE:HL by B bits (B > 0) + or a ; clear carry + rl l ; rotate L thru carry + rl h ; rotate H thru carry + rl e ; rotate E thru carry + rl d ; rotate D thru carry + djnz rl32 ; loop B times + ret ; done + +err_nodisk: + ld hl,str_err_nodisk + jr err +err_noslice: + ld hl,str_err_noslice + jr err +err_diskio: + ld hl,str_err_diskio + jr err +err_sig: + ld hl,str_err_sig + jr err +err_api: + ld hl,str_err_api + jr err +err: + push hl + ld de,str_err_prefix + call writestr + pop de + call writestr + halt + +str_err_prefix db "\r\n\r\n*** ","$" +str_err_nodisk db "Disk unit not available","$" +str_err_noslice db "Disk unit does not support slices","$" +str_err_diskio db "Disk I/O failure","$" +str_err_sig db "No system image on disk","$" +str_err_api db "HBIOS API failure","$" + msgunit db 13,10,13,10,'Boot CP/M 3 from Disk Unit: $' msgslc db ' Slice: $' msginv db 13,10,13,10,'*** Invalid Selection ***$' @@ -363,129 +539,143 @@ crlf db 13,10,'$' dpb$start: dpb$rom: ; 384K ROM Drive - dw 64 ; spt: sectors per track - db 4 ; bsh: block shift factor - db 15 ; blm: block mask - db 1 ; exm: extent mask - dw 192 - 1 ; dsm: total storage in blocks - 1 = (384kb / 2k bls) - 1 = 191 - dw 256 - 1 ; drm: dir entries - 1 = 256 - 1 = 255 - db 11110000b ; al0: dir blk bit map, first byte - db 00000000b ; al1: dir blk bit map, second byte - dw 8000h ; cks: directory check vector size - permanent storage = 8000H - dw 0 ; off: reserved tracks = 16 trks * (16 trks * 16 heads * 16 secs * 512 bytes) = 128k + dw 64 ; spt: sectors per track + db 4 ; bsh: block shift factor + db 15 ; blm: block mask + db 1 ; exm: extent mask + dw 192 - 1 ; dsm: total storage in blocks - 1 = (384kb / 2k bls) - 1 = 191 + dw 256 - 1 ; drm: dir entries - 1 = 256 - 1 = 255 + db 11110000b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 8000h ; cks: directory check vector size - permanent storage = 8000H + dw 0 ; off: reserved tracks = 16 trks * (16 trks * 16 heads * 16 secs * 512 bytes) = 128k db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 dpb$sz equ $ - dpb$start dpb$ram: ; 256K RAM Drive - dw 64 ; spt: sectors per track - db 4 ; bsh: block shift factor - db 15 ; blm: block mask - db 1 ; exm: extent mask - dw 128 - 1 ; dsm: total storage in blocks - 1 = (256kb / 2k bls) - 1 = 127 - dw 256 - 1 ; drm: dir entries - 1 = 256 - 1 = 255 - db 11110000b ; al0: dir blk bit map, first byte - db 00000000b ; al1: dir blk bit map, second byte - dw 8000h ; cks: directory check vector size - permanent storage = 8000H - dw 0 ; off: reserved tracks = 16 trks * (16 trks * 16 heads * 16 secs * 512 bytes) = 128k + dw 64 ; spt: sectors per track + db 4 ; bsh: block shift factor + db 15 ; blm: block mask + db 1 ; exm: extent mask + dw 128 - 1 ; dsm: total storage in blocks - 1 = (256kb / 2k bls) - 1 = 127 + dw 256 - 1 ; drm: dir entries - 1 = 256 - 1 = 255 + db 11110000b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 8000h ; cks: directory check vector size - permanent storage = 8000H + dw 0 ; off: reserved tracks = 16 trks * (16 trks * 16 heads * 16 secs * 512 bytes) = 128k db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 dpb$rf: ; 4MB RAM Floppy Drive - dw 64 ; spt: sectors per track - db 4 ; bsh: block shift factor - db 15 ; blm: block mask - db 0 ; exm: extent mask - dw 2047 ; dsm: total storage in blocks - 1 = (4mb / 2k bls) - 1 = 2047 - dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 - db 11110000b ; al0: dir blk bit map, first byte - db 00000000b ; al1: dir blk bit map, second byte - dw 8000h ; cks: directory check vector size - permanent storage = 8000H - dw 0 ; off: reserved tracks = 0 trks + dw 64 ; spt: sectors per track + db 4 ; bsh: block shift factor + db 15 ; blm: block mask + db 0 ; exm: extent mask + dw 2047 ; dsm: total storage in blocks - 1 = (4mb / 2k bls) - 1 = 2047 + dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 + db 11110000b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 8000h ; cks: directory check vector size - permanent storage = 8000H + dw 0 ; off: reserved tracks = 0 trks db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 dpb$hd: ; 8MB Hard Disk Drive - dw 64 ; spt: sectors per track - db 5 ; bsh: block shift factor - db 31 ; blm: block mask - db 1 ; exm: extent mask - dw 2047 ; dsm: total storage in blocks - 1 = (8mb / 4k bls) - 1 = 2047 - dw 511 ; drm: dir entries - 1 = 512 - 1 = 511 - db 11110000b ; al0: dir blk bit map, first byte - db 00000000b ; al1: dir blk bit map, second byte - dw 8000h ; cks: directory check vector size - permanent storage = 8000H - dw 16 ; off: reserved tracks = 16 trks * (16 trks * 16 heads * 16 secs * 512 bytes) = 128k + dw 64 ; spt: sectors per track + db 5 ; bsh: block shift factor + db 31 ; blm: block mask + db 1 ; exm: extent mask + dw 2047 ; dsm: total storage in blocks - 1 = (8mb / 4k bls) - 1 = 2047 + dw 512-1 ; drm: dir entries - 1 = 512 - 1 = 511 + db 11110000b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 8000h ; cks: directory check vector size - permanent storage = 8000H + dw 16 ; off: reserved tracks = 16 trks * (16 trks * 16 heads * 16 secs * 512 bytes) = 128k db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 dpb$fd720: ; 3.5" DS/DD Floppy Drive (720K) - dw 36 ; spt: sectors per track - db 4 ; bsh: block shift factor - db 15 ; blm: block mask - db 0 ; exm: extent mask - dw 350 ; dsm: total storage in blocks - 1 blk = ((720k - 18k off) / 2k bls) - 1 = 350 - dw 127 ; drm: dir entries - 1 = 128 - 1 = 127 - db 11000000b ; al0: dir blk bit map, first byte - db 00000000b ; al1: dir blk bit map, second byte - dw 32 ; cks: directory check vector size = 128 / 4 - dw 4 ; off: reserved tracks = 4 trks * (512 b/sec * 36 sec/trk) = 18k + dw 36 ; spt: sectors per track + db 4 ; bsh: block shift factor + db 15 ; blm: block mask + db 0 ; exm: extent mask + dw 350 ; dsm: total storage in blocks - 1 blk = ((720k - 18k off) / 2k bls) - 1 = 350 + dw 127 ; drm: dir entries - 1 = 128 - 1 = 127 + db 11000000b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 32 ; cks: directory check vector size = 128 / 4 + dw 4 ; off: reserved tracks = 4 trks * (512 b/sec * 36 sec/trk) = 18k db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 dpb_fd144: ; 3.5" DS/HD Floppy Drive (1.44M) - dw 72 ; spt: sectors per track - db 4 ; bsh: block shift factor - db 15 ; blm: block mask - db 0 ; exm: extent mask - dw 710 ; dsm: total storage in blocks - 1 blk = ((1,440k - 18k off) / 2k bls) - 1 = 710 - dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 - db 11110000b ; al0: dir blk bit map, first byte - db 00000000b ; al1: dir blk bit map, second byte - dw 64 ; cks: directory check vector size = 256 / 4 - dw 2 ; off: reserved tracks = 2 trks * (512 b/sec * 72 sec/trk) = 18k + dw 72 ; spt: sectors per track + db 4 ; bsh: block shift factor + db 15 ; blm: block mask + db 0 ; exm: extent mask + dw 710 ; dsm: total storage in blocks - 1 blk = ((1,440k - 18k off) / 2k bls) - 1 = 710 + dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 + db 11110000b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 64 ; cks: directory check vector size = 256 / 4 + dw 2 ; off: reserved tracks = 2 trks * (512 b/sec * 72 sec/trk) = 18k db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 -dpb_fd360: ; 5.25" DS/DD Floppy Drive (360K) - dw 36 ; spt: sectors per track - db 4 ; bsh: block shift factor - db 15 ; blm: block mask - db 1 ; exm: extent mask - dw 170 ; dsm: total storage in blocks - 1 blk = ((360k - 18k off) / 2k bls) - 1 = 170 - dw 127 ; drm: dir entries - 1 = 128 - 1 = 127 - db 11110000b ; al0: dir blk bit map, first byte - db 00000000b ; al1: dir blk bit map, second byte - dw 32 ; cks: directory check vector size = 128 / 4 - dw 4 ; off: reserved tracks = 4 trks * (512 b/sec * 36 sec/trk) = 18k +dpb_fd360: ; 5.25" DS/DD Floppy Drive (360K) + dw 36 ; spt: sectors per track + db 4 ; bsh: block shift factor + db 15 ; blm: block mask + db 1 ; exm: extent mask + dw 170 ; dsm: total storage in blocks - 1 blk = ((360k - 18k off) / 2k bls) - 1 = 170 + dw 127 ; drm: dir entries - 1 = 128 - 1 = 127 + db 11110000b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 32 ; cks: directory check vector size = 128 / 4 + dw 4 ; off: reserved tracks = 4 trks * (512 b/sec * 36 sec/trk) = 18k db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 dpb_fd120: ; 5.25" DS/HD Floppy Drive (1.2M) - dw 60 ; spt: sectors per track - db 4 ; bsh: block shift factor - db 15 ; blm: block mask - db 0 ; exm: extent mask - dw 591 ; dsm: total storage in blocks - 1 blk = ((1,200k - 15k off) / 2k bls) - 1 = 591 - dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 - db 11110000b ; al0: dir blk bit map, first byte - db 00000000b ; al1: dir blk bit map, second byte - dw 64 ; cks: directory check vector size = 256 / 4 - dw 2 ; off: reserved tracks = 2 trks * (512 b/sec * 60 sec/trk) = 15k + dw 60 ; spt: sectors per track + db 4 ; bsh: block shift factor + db 15 ; blm: block mask + db 0 ; exm: extent mask + dw 591 ; dsm: total storage in blocks - 1 blk = ((1,200k - 15k off) / 2k bls) - 1 = 591 + dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 + db 11110000b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 64 ; cks: directory check vector size = 256 / 4 + dw 2 ; off: reserved tracks = 2 trks * (512 b/sec * 60 sec/trk) = 15k db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 dpb_fd111: ; 8" DS/DD Floppy Drive (1.11M) - dw 60 ; spt: sectors per track - db 4 ; bsh: block shift factor - db 15 ; blm: block mask - db 0 ; exm: extent mask - dw 569 ; dsm: total storage in blocks - 1 blk = ((1,155k - 15k off) / 2k bls) - 1 = 569 - dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 - db 11110000b ; al0: dir blk bit map, first byte - db 00000000b ; al1: dir blk bit map, second byte - dw 64 ; cks: directory check vector size = 256 / 4 - dw 2 ; off: reserved tracks = 2 trks * (512 b/sec * 60 sec/trk) = 15k + dw 60 ; spt: sectors per track + db 4 ; bsh: block shift factor + db 15 ; blm: block mask + db 0 ; exm: extent mask + dw 569 ; dsm: total storage in blocks - 1 blk = ((1,155k - 15k off) / 2k bls) - 1 = 569 + dw 255 ; drm: dir entries - 1 = 256 - 1 = 255 + db 11110000b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 64 ; cks: directory check vector size = 256 / 4 + dw 2 ; off: reserved tracks = 2 trks * (512 b/sec * 60 sec/trk) = 15k + db 2 ; psh: 2 for 512 byte sectors + db 3 ; phm: (512 / 128) - 1 + +dpb$hdnew: ; 8MB Hard Disk Drive (new format) + dw 64 ; spt: sectors per track + db 5 ; bsh: block shift factor + db 31 ; blm: block mask + db 1 ; exm: extent mask + dw 2048 - 1 - 4 ; dsm: total storage in blocks - 1 = 2048 - 1 - resvd tracks + dw 1024 - 1 ; drm: dir entries + db 11111111b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 8000h ; cks: directory check vector size - permanent storage = 8000H + dw 2 ; off: reserved tracks db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 @@ -493,13 +683,13 @@ dph0: dw 0 ; xlt, 0 means no translation db 0,0,0,0,0,0,0,0,0 ; scratch (9 bytes) db 0 ; mf: media flag dw dpb$hd ; dpb - dw csvbuf ; csv: - dw alvbuf ; alv: + dw csvbuf ; csv: + dw alvbuf ; alv: dw dirbcb ; dirbcb dw dtabcb ; dtabcb dw 0ffffh ; hash (disabled) db 0 ; hbank - + dtbl: dtbl dph0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dirbcb: db 0ffh ; drv @@ -524,6 +714,10 @@ trk ds 2 ; current track sect ds 2 ; current sector dma ds 2 ; current DMA address +medid ds 1 ; media id +lba ds 4 ; current lba +sps ds 2 ; sectors per slice + csvbuf ds 128 ; length (CSV) = ((DRM+1)/4) alvbuf ds 512 ; length (ALV) = ((DSM+1)/4) dirbuf ds 512 ; sector buffer @@ -531,6 +725,6 @@ dtabuf ds 512 ; sector buffer ds 64 stack equ $ -stksav dw 0 +stksav ds 2 end diff --git a/Source/CPM3/boot.z80 b/Source/CPM3/boot.z80 index 53e36f47..e84adb31 100644 --- a/Source/CPM3/boot.z80 +++ b/Source/CPM3/boot.z80 @@ -41,7 +41,7 @@ tpa$bank equ 0 if banked ; Clone page zero from bank 0 to additional banks - ld b,3 ; last bank + ld b,4 ; last bank ld c,0 ; src bank init$2: push bc ; save bank id's diff --git a/Source/CPM3/diskio.z80 b/Source/CPM3/diskio.z80 index 154d601d..d9f3ccb1 100644 --- a/Source/CPM3/diskio.z80 +++ b/Source/CPM3/diskio.z80 @@ -37,7 +37,7 @@ extrn ?bnkxlt - ;extrn phex8, cout + extrn phex8, cout ; CP/M 3 Disk definition macros @@ -62,6 +62,7 @@ bell equ 7 dw dsk$init db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) dph0: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read @@ -69,6 +70,7 @@ dph0: dph 0,dpb$max ; Real DPB filled in at disk login dw dsk$init db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) dph1: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read @@ -76,6 +78,7 @@ dph1: dph 0,dpb$max ; Real DPB filled in at disk login dw dsk$init db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) dph2: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read @@ -83,6 +86,7 @@ dph2: dph 0,dpb$max ; Real DPB filled in at disk login dw dsk$init db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) dph3: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read @@ -90,6 +94,7 @@ dph3: dph 0,dpb$max ; Real DPB filled in at disk login dw dsk$init db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) dph4: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read @@ -97,6 +102,7 @@ dph4: dph 0,dpb$max ; Real DPB filled in at disk login dw dsk$init db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) dph5: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read @@ -104,6 +110,7 @@ dph5: dph 0,dpb$max ; Real DPB filled in at disk login dw dsk$init db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) dph6: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read @@ -111,6 +118,7 @@ dph6: dph 0,dpb$max ; Real DPB filled in at disk login dw dsk$init db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) dph7: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read @@ -118,6 +126,7 @@ dph7: dph 0,dpb$max ; Real DPB filled in at disk login dw dsk$init db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) dph8: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read @@ -125,6 +134,7 @@ dph8: dph 0,dpb$max ; Real DPB filled in at disk login dw dsk$init db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) dph9: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read @@ -132,6 +142,7 @@ dph9: dph 0,dpb$max ; Real DPB filled in at disk login dw dsk$init db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) dph10: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read @@ -139,6 +150,7 @@ dph10: dph 0,dpb$max ; Real DPB filled in at disk login dw dsk$init db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) dph11: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read @@ -146,6 +158,7 @@ dph11: dph 0,dpb$max ; Real DPB filled in at disk login dw dsk$init db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) dph12: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read @@ -153,6 +166,7 @@ dph12: dph 0,dpb$max ; Real DPB filled in at disk login dw dsk$init db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) dph13: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read @@ -160,6 +174,7 @@ dph13: dph 0,dpb$max ; Real DPB filled in at disk login dw dsk$init db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) dph14: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset dw dsk$write dw dsk$read @@ -167,6 +182,7 @@ dph14: dph 0,dpb$max ; Real DPB filled in at disk login dw dsk$init db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) dph15: dph 0,dpb$max ; Real DPB filled in at disk login + dw 0, 0 ; LBA Offset cseg ; DPB must be resident @@ -176,8 +192,8 @@ dpb$max: db 31 ; blm: block mask db 1 ; exm: extent mask dw 2047 ; dsm: total storage in blocks - 1 = (8mb / 4k bls) - 1 = 2047 - dw 511 ; drm: dir entries - 1 = 512 - 1 = 511 - db 11110000b ; al0: dir blk bit map, first byte + dw 1024 - 1 ; drm: dir entries - 1 + db 11111111b ; al0: dir blk bit map, first byte db 00000000b ; al1: dir blk bit map, second byte dw 64 ; cks: directory check vector size - 256 / 4 dw 0 ; off: reserved tracks = 16 trks * (16 trks * 16 heads * 16 secs * 512 bytes) = 128k @@ -228,13 +244,13 @@ dpb$rf: ; 4MB RAM Floppy Drive db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 -dpb$hd: ; 8MB Hard Disk Drive +dpb$hd: ; 8MB Hard Disk Drive w/ 512 dir entries dw 64 ; spt: sectors per track db 5 ; bsh: block shift factor db 31 ; blm: block mask db 1 ; exm: extent mask dw 2047 ; dsm: total storage in blocks - 1 = (8mb / 4k bls) - 1 = 2047 - dw 511 ; drm: dir entries - 1 = 512 - 1 = 511 + dw 512 - 1 ; drm: dir entries - 1 = 512 - 1 = 511 db 11110000b ; al0: dir blk bit map, first byte db 00000000b ; al1: dir blk bit map, second byte dw 8000h ; cks: directory check vector size - permanent storage = 8000H @@ -312,6 +328,20 @@ dpb_fd111: ; 8" DS/DD Floppy Drive (1.11M) db 2 ; psh: 2 for 512 byte sectors db 3 ; phm: (512 / 128) - 1 +dpb$hdnew: ; 8MB Hard Disk Drive (new format) + dw 64 ; spt: sectors per track + db 5 ; bsh: block shift factor + db 31 ; blm: block mask + db 1 ; exm: extent mask + dw 2048 - 1 - 4 ; dsm: total storage in blocks - 1 = 2048 - 1 - resvd tracks + dw 1024 - 1 ; drm: dir entries + db 11111111b ; al0: dir blk bit map, first byte + db 00000000b ; al1: dir blk bit map, second byte + dw 8000h ; cks: directory check vector size - permanent storage = 8000H + dw 2 ; off: reserved tracks + db 2 ; psh: 2 for 512 byte sectors + db 3 ; phm: (512 / 128) - 1 + dseg ; rest is banked @@ -370,48 +400,152 @@ dsk$login: ;ld a,'L' ;call cout + + ld (curdph),de ; save working DPH + ex de,hl ; DPH adr to HL + dec hl ; point to slice + ld a,(hl) ; get slice + ld (slice),a ; save it + dec hl ; point to disk unit + ld a,(hl) ; get unit + ld (unit),a ; save it + call media ; update DPH for media + ; Need to do something on error, but bioskrnl provides + ; no way for us to return an error. + ;jr nz,??? + ret - push de ; save DPH ptr +media: + ; Set retry address + ld hl,media + ld (retry$adr),hl - ; check media - ld a,(@rdrv) ; get disk unit - ;halt - ld c,a ; put in C - ld b,18h ; HBIOS Media function - ld e,1 ; Enable media check/discovery - ;rst 08 - call 0FFF0H ; HBIOS call - ld a,e ; Resultant media id to accum - or a ; Set flags - ;halt - ; - ; !!! Need to do something on error !!! - ; - jr nz,dsk$login0 ; continue if OK - pop de ; else error - ret ; return + ; Sense media to determine media format + ld a,(unit) ; Get disk unit + ld c,a ; put in C + ld b,18h ; HBIOS Media function + ld e,1 ; Enable media check/discovery + call 0FFF0H ; HBIOS call + jp nz,err_diskio ; handle error + ld a,e ; resultant media id to accum + ld (medid),a ; save media id + or a ; set flags, 0 is no media + jp z,err_diskio ; handle no media error + + ; Initialize slice start LBA & sectors per slice + ld hl,0 ; assume slice starts + ld (lba),hl ; ... at LBA offset + ld (lba+2),hl ; ... of zero + ld hl,16640 ; assume legacy value for + ld (sps),hl ; ... sectors per slice + + ; If not hard disk, skip partition & slice stuff + ld a,(medid) ; get media id + cp 4 ; hard disk? + jr nz,media9 ; if not, jump ahead + + ; Read MBR + ld de,8000h ; LBA address zero + ld hl,0 ; ... to read first sector + ld bc,mbrsec ; read into MBR buffer + ld (dma),bc ; save + ld a,(0FFE0h) ; get current HBIOS bank + ld (bank),a ; set DMA bank + ld a,(unit) ; get bootunit + ld c,a ; put in C + ld b,013h ; HBIOS func: disk read + call dsk$io ; do it, no return on err + + ; Check signature + ld hl,(mbrsec+1FEh) ; get signature + ld a,l ; first byte + cp 055h ; should be $55 + jr nz,media5 ; if not, no part table + ld a,h ; second byte + cp 0AAh ; should be $AA + jr nz,media5 ; if not, no part table + + ; Search part table for CP/M entry (type 0x52) + ld b,4 ; four entries in part table + ld hl,mbrsec+1BEh+4 ; offset of first part type +media3: + ld a,(hl) ; get part type + cp 52h ; CP/M partition? + jr z,media4 ; cool, grab the LBA offset + ld de,16 ; part table entry size + add hl,de ; bump to next part type + djnz media3 ; loop thru table + jr media5 ; too bad, no CP/M partition + +media4: + ; Capture the starting LBA of the CP/M partition we found + ld de,4 ; LBA is 4 bytes after part type + add hl,de ; point to it + ld de,lba ; loc to store lba offset + ld bc,4 ; 4 bytes (32 bits) + ldir ; copy it + + ; For now, it is implied that a slice within a partition + ; table will be in the "new" disk format. So, we now + ; adjust the sectors per slice and media id. + + ; Use new slice format sectors per slice value + ld hl,16384 ; new sectors per slice + ld (sps),hl ; save it + + ; Update media id for new hard disk format + ld a,10 ; new media id + ld (medid),a ; save it + +media5: + ; Adjust LBA offset based on target slice + ld a,(slice) ; get boot slice, A is loop cnt + ld hl,(lba) ; set DE:HL + ld de,(lba+2) ; ... to starting LBA + ld bc,(sps) ; sectors per slice +boot6: + or a ; set flags to check loop cntr + jr z,boot8 ; done if counter exhausted + add hl,bc ; add one slice to low word + jr nc,boot7 ; check for carry + inc de ; if so, bump high word +boot7: + dec a ; dec loop downcounter + jr boot6 ; and loop +boot8: + ld (lba),hl ; save new lba, low word + ld (lba+2),de ; save new lba, high word -dsk$login0: +media9: + ; Locate DPB corresponding to media id ld hl,dpb$start - dpb$sz ld de,dpb$sz - ld b,a ; loop count -dsk$login1: - add hl,de ; next dpb - djnz dsk$login1 ; loop as needed - - ; hl is ptr to desired dpb - pop de ; restore DPH ptr - ;halt - ex de,hl ; de = DPB adr, hl = DPH adr - push de ; save DPB adr - ld de,12 ; offset of DPB in DPH - add hl,de ; hl = adr of DPB field in DPH - pop de ; recover DPB adr - ld (hl),e ; update LSB - inc hl - ld (hl),d ; udpate MSB - ret ; done - + ld a,(medid) ; get media id + ld b,a ; to loop count +media10: + add hl,de ; next dpb + djnz media10 ; loop as needed + + ; Stuff DPB ptr (HL) and LBA offset into DPH + ; DPH: DPB @ +12, LBA @ +25 + ld de,(curdph) ; load DPH pointer + ex de,hl ; de = DPB adr, hl = DPH adr + push de ; save DPB adr + ld de,12 ; offset of DPB in DPH + add hl,de ; hl = adr of DPB field in DPH + pop de ; recover DPB adr + ld (hl),e ; update LSB + inc hl ; point to MSB + ld (hl),d ; update MSB + ld de,12 ; 12 more bytes to LBA + add hl,de ; HL points to LBA offset field + ld de,lba ; DE points to LBA offset + ex de,hl ; swap for copy + ld bc,4 ; 4 bytes + ldir ; do it + + xor a ; signal success + ret ; done ; disk READ and WRITE entry points. @@ -429,116 +563,119 @@ dsk$login1: ; if necessary, then return an error code in dsk$read: -; ld ix,30H -; halt + ld a,13h ; HBIOS disk read function + ld (func),a ; save it + jr dsk$rw ; common disk read/write code - ;ld a,'R' - ;call cout - - push de ; save XDPH pointer - call dsk$seek ; disk seek - pop hl ; restore pointer to HL - ret nz ; abort on seek error -; - dec hl ; point to unit field of XDPH - dec hl - ld c,(hl) ; BIOS Disk Unit in C - ld b,13H ; HBIOS READ function - ld hl,(@dma) ; Dest buffer adr - if banked - ld a,(@dbnk) ; destination bank - call ?bnkxlt - else - ld a,(0FFE0H) ; get current bank - endif - ld d,a ; set desk bank - ld e,1 ; 1 sector - rst 08 ; do it - ;call 0FFF0H - - ;call phex8 - ret ; return +dsk$write: + ld a,14h ; HBIOS disk write function + ld (func),a ; save it + jr dsk$rw ; common disk read/write code -; lxi h,read$msg ; point at " Read " -; mvi a,88h ! mvi b,01h ; 1797 read + Z80DMA direction -; jmp rw$common +dsk$rw: + ; Common disk read/write routine + ; Assumes func is set to HBIOS read or write + + ; Save XDPH address + ld (curdph),de ; save to curdph -dsk$write: - ;ld ix,32H - ;halt + ; Set retry address + ld hl,dsk$rw + ld (retry$adr),hl + + ; Check device type + ld a,(@rdrv) ; get unit + ld c,a ; BIOS Disk Unit in C + ld b,17h ; HBIOS DEVICE function + call 0FFF0h ; do it, D=device type + ld a,d ; put in accum + and 0F0h ; isolate high bits + cp 10h ; floppy? + jr nz,dsk$rw2 ; if not, do LBA i/o + + ; Floppy I/O + ld de,(@sect) ; sector -> de, head(d) becomes zero + ld hl,(@trk) ; track -> hl (low bit has head) + srl h ; shift head bit out of hl + rr l ; ... and into carry + rl d ; carry bit (head) into d + jr dsk$rw9 ; do the disk I/O - push de ; save XDPH pointer - call dsk$seek ; disk seek - pop hl ; restore pointer to XDPH - ret nz ; abort on seek error -; - dec hl ; point to unit field of XDPH - dec hl - ld c,(hl) ; BIOS Disk Unit in C - ld b,14H ; HBIOS WRITE function - ld hl,(@dma) ; Dest buffer adr +dsk$rw2: + ; LBA IO: Get LBA offset from DPH + ld hl,(curdph) ; HL := DPH adr + ld de,25+3 ; LBA value + 3 + add hl,de ; HL := LBA offset (last byte!) + ld b,(hl) ; hibyte of hiword + dec hl ; bump + ld c,(hl) ; lobyte of hiword + dec hl ; bump + push bc ; save hiword + ld b,(hl) ; hibyte of loword + dec hl ; bump + ld c,(hl) ; lobyte of loword + dec hl ; bump + push bc ; save loword + + ; Get track and shift into correct bits + ld hl,(@trk) ; get track + ld de,0 ; clear hiword + ld b,4 ; x16 (16 spt assumed) + call rl32 ; do it + + ; Combine with sector + ld a,(@sect) ; get sector + or l ; combine + ld l,a ; and back to L + + ; Add in LBA offset + pop bc ; lba offset loword + add hl,bc ; add to cur loword + ex de,hl ; swap + pop bc ; lba offset hiword + adc hl,bc ; add w/ carry to cur hiword + ex de,hl ; swap back + set 7,d ; set lba access bit + +dsk$rw9: + ; DE:HL has sector address to read (LBA or CHS) + ld bc,(@dma) ; get dma address + ld (dma),bc ; save for dsk$io if banked - ld a,(@dbnk) ; destination bank - call ?bnkxlt + ld a,(@dbnk) ; destination bank + call ?bnkxlt ; xlat to HBIOS else - ld a,(0FFE0H) ; get current bank + ld a,(0FFE0H) ; get current bank endif - ld d,a ; set desk bank - ld e,1 ; 1 sector - rst 08 ; do it - ;call 0FFF0H - ret ; return - -; lxi h,write$msg ; point at " Write " -; mvi a,0A8h ! mvi b,05h ; 1797 write + Z80DMA direction -; ; jmp wr$common - -dsk$seek: - dec de ; point to unit field of XDPH - dec de - ld a,(de) ; get it - ld c,a ; BIOS Disk Unit in C - ld b,12H ; HBIOS SEEK function - push bc ; save it - push de ; save XDPH pointer - ld b,17h ; HBIOS DEVICE function - rst 08 ; Do it, D=device type - ld a,d ; put in accum - and 0F0h ; isolate high bits - ld b,1 ; assume it is floppy, 1 head bit - ld c,01h ; 1 bit head mask - cp 10h ; floppy? - jr z,seek0 ; yup, skip ahead - ld b,4 ; must be hard disk, 4 head bits - ld c,0Fh ; 4 bit head mask -seek0: - pop de ; recover XDPH pointer - push bc ; save bc - inc de ; point to slice field of XDPH - ld a,(de) ; get it - ld e,a ; slice to E - ld h,65 ; number of tracks per slice - call mult8 ; HL now has track offset for slice - pop bc ; recover bc - push hl ; save track offset for now - ld hl,(@trk) ; get track value - ld a,l ; lsb of track to a - and c ; apply mask - ld d,a ; save in d -seek1: - srl h ; shift one bit out - rr l ; ... of hl - djnz seek1 ; do all bits - ld a,(@sect) ; get sector - ld e,a ; stuff it in e - ex de,hl ; de=track, hl=head/sect - ex (sp),hl ; save head/sect, hl = offset - add hl,de ; hl has final track value - pop de ; recover head/sect to de - pop bc ; recover function & unit - rst 08 ; perform seek - ;call 0FFF0H - ret + ld (bank),a + ld a,(func) ; get HBIOS func code + ld b,a ; put in B + ld a,(@rdrv) ; get disk unit + ld c,a ; put in C + ;jr dsk$io ; fall thru to dsk$io! + +dsk$io: + ; Read/write a disk sector + ; DE:HL is CHS/LBA, B is HBIOS func, C is disk unit + + ; Seek to requested sector in DE:HL + push bc ; save func & unit + ld b,012h ; HBIOS func: seek + call 0FFF0h ; do it + pop bc ; recover func & unit + jp nz,err_diskio ; handle error + + ; Read sector(s) into buffer + ld e,1 ; transfer count + ld hl,(dma) ; read into info sec buffer + ld a,(bank) ; HBIOS DMA bank + ld d,a ; put in D + call 0FFF0h ; do it + jp nz,err_diskio ; handle error + xor a ; signal success + ret ; and done + + ; ; multiply 8-bit values @@ -557,6 +694,93 @@ mult8_noadd: djnz mult8_loop ret +rl32: + ; Left shift DE:HL by B bits (B > 0) + or a ; clear carry + rl l ; rotate L thru carry + rl h ; rotate H thru carry + rl e ; rotate E thru carry + rl d ; rotate D thru carry + djnz rl32 ; loop B times + ret ; done + +cin$echo: ; get console input, echo it, and shift to upper case + call ?const ; check for char + or a ; set flags + jr z,cin$echo1 ; nope, continue + call ?conin ; eat extraneous char + jr cin$echo ; and loop +cin$echo1: + call ?conin ; get char + push af ; save it + ld c,a ; put in C + call ?cono ; echo + pop af ; recover it + cp 'a' ; compare + ret c ; done if carry + sub 'a' - 'A' ; make upper case + ret ; and done + +; call ?const ! ora a ! jz u$c1 ; see if any char already struck +; call ?conin ! jmp u$conin$echo ; yes, eat it and try again +;u$c1: +; call ?conin ! push psw +; mov c,a ! call ?cono +; pop psw ! cpi 'a' ! rc +; sui 'a'-'A' ; make upper case +; ret + + +err_nodisk: + ld hl,str_err_nodisk + jr err +err_noslice: + ld hl,str_err_noslice + jr err +err_diskio: + ld hl,str_err_diskio + jr err +err_sig: + ld hl,str_err_sig + jr err +err_api: + ld hl,str_err_api + jr err +err: + push hl + call ?pderr + pop hl + call ?pmsg + ld hl,str_err_retry + call ?pmsg + call cin$echo + cp 'Y' + ret nz + ld hl,(retry$adr) + jp (hl) + +str_err_retry db ", Retry (Y/N) ? ",0 +str_err_nodisk db ", No disk",0 +str_err_noslice db ", No slice",0 +str_err_diskio db ", Disk I/O",0 +str_err_sig db ", No system",0 +str_err_api db ", API failure",0 + +; +; +; +retry$adr dw ?wboot ; error retry address +curdph dw 0 ; working dph value +medid db 0 ; working media id value +unit db 0 ; working disk unit num +slice db 0 ; working slice num +lba dw 0,0 ; working lba +sps dw 0 ; sectors per slice +mbrsec ds 512 ; MBR sector buffer +dma dw 0 ; current DMA address +bank db 0 ; HBIOS DMA bank +func db 0 ; HBIOS function + ;rw$common: ; seek to correct track (if necessary), ; ; initialize DMA controller, ; ; and issue 1797 command. diff --git a/Source/CPM3/genbnk.dat b/Source/CPM3/genbnk.dat index 4a542bd3..060a2c79 100644 --- a/Source/CPM3/genbnk.dat +++ b/Source/CPM3/genbnk.dat @@ -8,12 +8,12 @@ MEMTOP = FD BNKSWT = Y COMBAS = 80 LERROR = Y -NUMSEGS = 03 +NUMSEGS = 04 MEMSEG00 = 01,43,00 MEMSEG01 = 0E,72,02 MEMSEG02 = 01,7F,03 MEMSEG03 = 01,7F,04 -MEMSEG04 = 00,C0,05 +MEMSEG04 = 01,7F,05 MEMSEG05 = 00,C0,06 MEMSEG06 = 00,C0,07 MEMSEG07 = 00,C0,08 diff --git a/Source/CPM3/move.z80 b/Source/CPM3/move.z80 index 1b5dc067..73cc13bb 100644 --- a/Source/CPM3/move.z80 +++ b/Source/CPM3/move.z80 @@ -69,7 +69,8 @@ xbnkmov: ; 1: TPA BID_AUX 8Ch ; 2: BUFS BID_AUX-1 8Bh ; 3: BUFS BID_AUX-2 8Ah -; ... +; 4: BUFS BID_AUX-3 89h +; 5: BUFS BID_AUX-4 88h ; ; N.B., Below BID_AUX is considered RAM disk bank. Need to ; make sure RAM disk is kept small enough to stay below diff --git a/Source/CPM3/optzpm.lib b/Source/CPM3/optzpm.lib index eba22e9b..62c2499d 100644 --- a/Source/CPM3/optzpm.lib +++ b/Source/CPM3/optzpm.lib @@ -1,5 +1,4 @@ - ; global assembler options for BANKED BIOS - ; with Boot Drive swapped into Drive A + ; global assembler options for ZPM BIOS true equ -1 false equ not true diff --git a/Source/CPM3/util.z80 b/Source/CPM3/util.z80 index 28b39244..aa916129 100644 --- a/Source/CPM3/util.z80 +++ b/Source/CPM3/util.z80 @@ -51,7 +51,7 @@ bin2bcd1: pop bc ret - if 0 + if 1 ; ; Print the hex word value in HL ; diff --git a/Source/HBIOS/diskdefs b/Source/HBIOS/diskdefs index 937bfcf2..dad4c46e 100644 --- a/Source/HBIOS/diskdefs +++ b/Source/HBIOS/diskdefs @@ -297,121 +297,158 @@ diskdef wbw_rom1024 os 2.2 end -# UNA 512KB ROM (128KB reserved, 384KB ROM Disk) +# RomWBW 720K floppy media +diskdef wbw_fd720 + seclen 512 + tracks 160 + sectrk 9 + blocksize 2048 + maxdir 128 + skew 0 + boottrk 4 + os 2.2 +end -diskdef una_rom512 +# RomWBW 1.44M floppy media +diskdef wbw_fd144 seclen 512 - tracks 12 - sectrk 64 + tracks 160 + sectrk 18 blocksize 2048 maxdir 256 skew 0 - boottrk 0 + boottrk 2 os 2.2 end -# UNA 512KB ROM (128KB reserved, 896KB ROM Disk) +# RomWBW 360K floppy media +diskdef wbw_fd360 + seclen 512 + tracks 80 + sectrk 9 + blocksize 2048 + maxdir 128 + skew 0 + boottrk 4 + os 2.2 +end -diskdef una_rom1024 +# RomWBW 1.20M floppy media +diskdef wbw_fd120 seclen 512 - tracks 28 - sectrk 64 + tracks 160 + sectrk 15 blocksize 2048 maxdir 256 skew 0 - boottrk 0 + boottrk 2 os 2.2 end -# RomWBW 8MB Hard Disk, LU 0-3 +# RomWBW 8MB Hard Disk, first 4 slices +# Legacy format, 512 dir entries, 8,320 sectors / slice diskdef wbw_hd0 seclen 512 - tracks 65 - sectrk 256 + tracks 1040 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 1 + boottrk 16 os 2.2 end diskdef wbw_hd1 seclen 512 - tracks 130 - sectrk 256 + tracks 2080 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 66 + boottrk 1056 os 2.2 end diskdef wbw_hd2 seclen 512 - tracks 195 - sectrk 256 + tracks 3120 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 131 + boottrk 2096 os 2.2 end diskdef wbw_hd3 seclen 512 - tracks 260 - sectrk 256 + tracks 4160 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 196 + boottrk 3136 os 2.2 end -# RomWBW 720K floppy media -diskdef wbw_fd720 + +# RomWBW 8MB Hard Disk +# New format, 1024 dir entries, 8,192 sectors / slice +# Pure filesystem image, no prefix +diskdef wbw_hd_new seclen 512 - tracks 160 - sectrk 9 - blocksize 2048 - maxdir 128 + tracks 1024 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 4 + boottrk 2 os 2.2 end -# RomWBW 1.44M floppy media -diskdef wbw_fd144 +# RomWBW 8MB Hard Disk, first 4 slices +# New format, 1024 dir entries, 8,192 sectors / slice +# Assumes 256 sector (16 track) hard disk prefix +diskdef wbw_hd0_new seclen 512 - tracks 160 - sectrk 18 - blocksize 2048 - maxdir 256 + tracks 1040 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 2 + boottrk 18 os 2.2 end -# RomWBW 360K floppy media -diskdef wbw_fd360 +diskdef wbw_hd1_new seclen 512 - tracks 80 - sectrk 9 - blocksize 2048 - maxdir 128 + tracks 2064 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 4 + boottrk 1042 os 2.2 end -# RomWBW 1.20M floppy media -diskdef wbw_fd120 +diskdef wbw_hd2_new seclen 512 - tracks 160 - sectrk 15 - blocksize 2048 - maxdir 256 + tracks 3112 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 2 + boottrk 2066 + os 2.2 +end + +diskdef wbw_hd3_new + seclen 512 + tracks 4136 + sectrk 16 + blocksize 4096 + maxdir 1024 + skew 0 + boottrk 3114 os 2.2 end diff --git a/Source/HBIOS/romldr.asm b/Source/HBIOS/romldr.asm index 89ec8d62..db5f1750 100644 --- a/Source/HBIOS/romldr.asm +++ b/Source/HBIOS/romldr.asm @@ -106,7 +106,7 @@ bid_cur .equ -1 ; used below to indicate current bank ; start: ld sp,bl_stack ; setup private stack - call DELAY_INIT ; init delay functions + call delay_init ; init delay functions ; ; Disable interrupts if IM1 is active because we are switching to page ; zero in user bank and it has not been prepared with IM1 vector yet. @@ -456,7 +456,7 @@ setcon: ld hl,str_newcon ; new console msg call pstr ; print string on cur console pop af ; restore new console unit - call PRTDECB ; print unit num + call prtdecb ; print unit num ; ; Set console unit ld b,BF_SYSPOKE ; HBIOS func: POKE @@ -479,7 +479,7 @@ setcon: reboot: ld hl,str_reboot ; point to message call pstr ; print it - call LDELAY ; wait for message to display + call ldelay ; wait for message to display ; #if (BIOS == BIOS_WBW) ; @@ -618,11 +618,11 @@ diskboot: ld hl,str_boot1 call pstr ld a,(bootunit) - call PRTDECB + call prtdecb ld hl,str_boot2 call pstr ld a,(bootslice) - call PRTDECB + call prtdecb ; #if (DSKYENABLE) ld hl,msg_load ; point to load message @@ -632,13 +632,21 @@ diskboot: #if (BIOS == BIOS_WBW) ; ; Check that drive actually exists - ld c,a ; put in C for func call + ;ld c,a ; put in C for func call ld b,BF_SYSGET ; HBIOS func: sys get ld c,BF_SYSGET_DIOCNT ; HBIOS sub-func: disk count rst 08 ; do it, E=disk count ld a,(bootunit) ; get boot disk unit cp e ; compare to count jp nc,err_nodisk ; handle no disk err +; + ; Sense media + ld a,(bootunit) ; get boot disk unit + ld c,a ; put in C for func call + ld b,BF_DIOMEDIA ; HBIOS func: media + ld e,1 ; enable media check/discovery + rst 08 ; do it + jp nz,err_diskio ; handle error ; ; If non-zero slice requested, confirm device can handle it ld a,(bootslice) ; get slice @@ -652,40 +660,6 @@ diskboot: cp DIODEV_IDE ; IDE is max slice device type jp c,err_noslice ; no such slice, handle err ; -diskboot1: - ; Sense media - ld a,(bootunit) ; get boot disk unit - ld c,a ; put in C for func call - ld b,BF_DIOMEDIA ; HBIOS func: media - ld e,1 ; enable media check/discovery - rst 08 ; do it - jp nz,err_diskio ; handle error - call pdot ; show progress -; - ; Seek to boot info sector, third sector - ld a,(bootslice) ; get boot slice - ld e,a ; move to E for mult - ld h,65 ; 65 tracks per slice - call MULT8 ; hl := h * e - ld de,$0002 ; head 0, sector 2 - ld b,BF_DIOSEEK ; HBIOS func: seek - ld a,(bootunit) ; get boot disk unit - ld c,a ; put in C - rst 08 ; do it - jp nz,err_diskio ; handle error - call pdot ; show progress -; - ; Read sector into local buffer - ld b,BF_DIOREAD ; HBIOS func: disk read - ld a,(bootunit) ; get boot disk unit - ld c,a ; put in C for func call - ld hl,bl_infosec ; read into info sec buffer - ld d,BID_USR ; user bank - ld e,1 ; transfer one sector - rst 08 ; do it - jp nz,err_diskio ; handle error - call pdot ; show progress -; #endif ; #if (BIOS == BIOS_UNA) @@ -712,12 +686,67 @@ diskboot1: jr z,diskboot1 ; if so, OK jp err_noslice ; no such slice, handle err ; +#endif +; diskboot1: + ; Initialize working LBA value + ld hl,0 ; zero HL + ld (lba),hl ; init + ld (lba+2),hl ; ... LBA +; + ; Set legacy sectors per slice + ld hl,16640 ; legacy sectors per slice + ld (sps),hl ; save it +; + ; Attempt to read MBR + ld de,0 ; MBR is at + ld hl,0 ; ... first sector + ld bc,bl_mbrsec ; read into MBR buffer + ld (dma),bc ; save + ld b,1 ; one sector + ld a,(bootunit) ; get bootunit + ld c,a ; put in C + call diskread ; do it + ret nz ; abort on error +; + ; Check signature + ld hl,(bl_mbrsec+$1FE) ; get signature + ld a,l ; first byte + cp $55 ; should be $55 + jr nz,diskboot1c ; if not, no part table + ld a,h ; second byte + cp $AA ; should be $AA + jr nz,diskboot1c ; if not, no part table +; + ; Try to find our entry in part table and capture lba offset + ld b,4 ; four entries in part table + ld hl,bl_mbrsec+$1BE+4 ; offset of first entry part type +diskboot1a: + ld a,(hl) ; get part type + cp $52 ; cp/m partition? + jr z,diskboot1b ; cool, grab the lba offset + ld de,16 ; part table entry size + add hl,de ; bump to next entry part type + djnz diskboot1a ; loop thru table + jr diskboot1c ; too bad, no cp/m partition +; +diskboot1b: + ; Capture the starting LBA of the CP/M partition we found + ld de,4 ; LBA is 4 bytes after part type + add hl,de ; point to it + ld de,lba ; loc to store lba offset + ld bc,4 ; 4 bytes (32 bits) + ldir ; copy it + ; If boot from partition, use new sectors per slice value + ld hl,16384 ; new sectors per slice + ld (sps),hl ; save it +; +diskboot1c: ; Add slice offset ld a,(bootslice) ; get boot slice, A is loop cnt - ld hl,0 ; DE:HL is LBA - ld de,0 ; ... initialize to zero - ld bc,16640 ; sectors per slice + ld hl,(lba) ; set DE:HL + ld de,(lba+2) ; ... to starting LBA + ld bc,(sps) ; sectors per slice diskboot2: or a ; set flags to check loop ctr jr z,diskboot4 ; done if counter exhausted @@ -729,30 +758,30 @@ diskboot3: jr diskboot2 ; and loop ; diskboot4: - ld (loadlba),hl ; save lba, low word - ld (loadlba+2),de ; save lba, high word + ld (lba),hl ; update lba, low word + ld (lba+2),de ; update lba, high word ; - ; Seek to boot info sector, third sector + push hl ; save HL + ld hl,str_ldsec ; display prefix + call pstr ; do it + pop hl ; restore HL + call prthex32 ; display starting sector + call pdot ; show progress +; + ; Read boot info sector, third sector ld bc,2 ; sector offset add hl,bc ; add to LBA value low word jr nc,diskboot5 ; check for carry inc de ; if so, bump high word diskboot5: - ld a,(bootunit) ; get disk unit to boot - ld b,a ; put in B for func call - ld c,$41 ; UNA func: set lba - rst 08 ; set lba - jp nz,err_api ; handle error + ld bc,bl_infosec ; read buffer + ld (dma),bc ; save + ld a,(bootunit) ; disk unit to read + ld c,a ; put in C + ld b,1 ; one sector + call diskread ; do it + ret nz ; abort on error call pdot ; show progress -; - ; Read sector into local buffer - ld c,$42 ; UNA func: read sectors - ld de,bl_infosec ; dest of cpm image - ld l,1 ; sectors to read - rst 08 ; do read - jp nz,err_diskio ; handle error -; -#endif ; ; Check signature ld de,(bb_sig) ; get signature read @@ -762,6 +791,7 @@ diskboot5: ld a,$5A ; expected value of second byte cp e ; compare jp nz,err_sig ; handle error + call pdot ; show progress ; ; Print disk boot info ; Volume "xxxxxxx" (0xXXXX-0xXXXX, entry @ 0xXXXX) @@ -774,17 +804,17 @@ diskboot5: call pstr ; print push hl ; save string ptr ld bc,(bb_cpmloc) ; get load loc - call PRTHEXWORD ; print it + call prthexword ; print it pop hl ; restore string ptr call pstr ; print push hl ; save string ptr ld bc,(bb_cpmend) ; get load end - call PRTHEXWORD ; print it + call prthexword ; print it pop hl ; restore string ptr call pstr ; print push hl ; save string ptr ld bc,(bb_cpment) ; get load end - call PRTHEXWORD ; print it + call prthexword ; print it pop hl ; restore string ptr call pstr ; print ; @@ -798,19 +828,25 @@ diskboot5: ld (loadcnt),a ; ... and save it call pdot ; show progress ; -#if (BIOS == BIOS_WBW) -; - ; Load image into memory - ld b,BF_DIOREAD ; HBIOS func: read sectors + ; Start OS load at sector 3 + ld hl,(lba) ; low word of saved LBA + ld de,(lba+2) ; high word of saved LBA + ld bc,3 ; offset for sector 3 + add hl,bc ; apply it + jr nc,diskboot6 ; check for carry + inc de ; bump high word if so +diskboot6: + ld bc,(bb_cpmloc) ; load address + ld (dma),bc ; and save it + ld a,(loadcnt) ; get sectors to read + ld b,a ; put in B ld a,(bootunit) ; get boot disk unit ld c,a ; put in C - ld hl,(bb_cpmloc) ; load address - ld d,BID_USR ; user bank - ld a,(loadcnt) ; get sectors to read - ld e,a ; number of sectors to load - rst 08 ; do it - jp nz,err_diskio ; handle errors + call diskread ; read image + ret nz ; abort on error call pdot ; show progress +; +#if (BIOS == BIOS_WBW) ; ; Record boot unit/slice ld b,BF_SYSSET ; hb func: set hbios parameter @@ -823,36 +859,10 @@ diskboot5: ld e,a ; save in E rst 08 jp nz,err_api ; handle errors - call pdot ; show progress ; #endif ; #if (BIOS == BIOS_UNA) -; - ; Start os load at sector 3 - ld hl,(loadlba) ; low word of saved LBA - ld de,(loadlba+2) ; high word of saved LBA - ld bc,3 ; offset for sector 3 - add hl,bc ; apply it - jr nc,diskboot6 ; check for carry - inc de ; bump high word if so -diskboot6: - ld c,$41 ; UNA func: set lba - ld a,(bootunit) ; get boot disk unit - ld b,a ; move to B - rst 08 ; set lba - jp nz,err_api ; handle error -; - ; Read OS image into memory - ld c,$42 ; UNA func: read sectors - ld a,(bootunit) ; get boot disk unit - ld b,a ; move to B - ld de,(bb_cpmloc) ; dest of cpm image - ld a,(loadcnt) ; get sectors to read - ld l,a ; sectors to read - rst 08 ; do read - jp nz,err_diskio ; handle error - call pdot ; show progress ; ; Record boot unit/slice ; UNA provides only a single byte to record the boot unit @@ -876,6 +886,8 @@ diskboot6: call pdot ; show progress ; #endif +; + call pdot ; show progress ; #if (DSKYENABLE) ld hl,msg_go ; point to go message @@ -886,6 +898,55 @@ diskboot6: ld hl,(bb_cpment) ; get entry vector jp (hl) ; and go there ; +; Read disk sector(s) +; DE:HL is LBA, B is sector count, C is disk unit +; +diskread: +; +#if (BIOS == BIOS_UNA) +; + ; Seek to requested sector in DE:HL + push bc ; save unit and count + ld b,c ; unit to read in B + ld c,$41 ; UNA func: set lba + rst 08 ; set lba + pop bc ; recover unit and count + jp nz,err_api ; handle error +; + ; Read sector(s) into buffer + ld l,b ; sectors to read + ld b,c ; unit to read in B + ld c,$42 ; UNA func: read sectors + ld de,(dma) ; dest for read + rst 08 ; do read + jp nz,err_diskio ; handle error + xor a ; signal success + ret ; and done +; +#endif +; +#if (BIOS == BIOS_WBW) +; + ; 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 + jp nz,err_diskio ; handle error +; + ; Read sector(s) into buffer + ld e,b ; transfer count + ld b,BF_DIOREAD ; HBIOS func: disk read + ld hl,(dma) ; read into info sec buffer + ld d,BID_USR ; user bank + rst 08 ; do it + jp nz,err_diskio ; handle error + xor a ; signal success + ret ; and done +; +#endif +; ;======================================================================= ; Utility functions ;======================================================================= @@ -1079,6 +1140,269 @@ isnum1: or $FF ; set NZ ret ; and done ; +; Delay 16us (cpu speed compensated) incuding call/ret invocation +; Register A and flags destroyed +; No compensation for z180 memory wait states +; There is an overhead of 3ts per invocation +; Impact of overhead diminishes as cpu speed increases +; +; cpu scaler (cpuscl) = (cpuhmz - 2) for 16us + 3ts delay +; note: cpuscl must be >= 1! +; +; example: 8mhz cpu (delay goal is 16us) +; loop = ((6 * 16) - 5) = 91ts +; total cost = (91 + 40) = 131ts +; actual delay = (131 / 8) = 16.375us +; + ; --- total cost = (loop cost + 40) ts -----------------+ +delay: ; 17ts (from invoking call) | + ld a,(cpuscl) ; 13ts | +; | +delay1: ; | + ; --- loop = ((cpuscl * 16) - 5) ts ------------+ | + dec a ; 4ts | | +#if (BIOS == BIOS_WBW) ; | | + #if (CPUFAM == CPU_Z180) ; | | + or a ; +4ts for z180 | | + #endif ; | | +#endif ; | | + jr nz,delay1 ; 12ts (nz) / 7ts (z) | | + ; ----------------------------------------------+ | +; | + ret ; 10ts (return) | + ;-------------------------------------------------------+ +; +; Delay 16us * DE (cpu speed compensated) +; Register DE, A, and flags destroyed +; No compensation for z180 memory wait states +; There is a 27ts overhead for call/ret per invocation +; Impact of overhead diminishes as DE and/or cpu speed increases +; +; cpu scaler (cpuscl) = (cpuhmz - 2) for 16us outer loop cost +; note: cpuscl must be > 0! +; +; Example: 8MHz cpu, DE=6250 (delay goal is .1 sec or 100,000us) +; inner loop = ((16 * 6) - 5) = 91ts +; outer loop = ((91 + 37) * 6250) = 800,000ts +; actual delay = ((800,000 + 27) / 8) = 100,003us +; + ; --- total cost = (outer loop + 27) ts ------------------------+ +vdelay: ; 17ts (from invoking call) | +; | + ; --- outer loop = ((inner loop + 37) * de) ts ---------+ | + ld a,(cpuscl) ; 13ts | | +; | | +vdelay1: ; | | + ; --- inner loop = ((cpuscl * 16) - 5) ts ------+ | | +#if (BIOS == BIOS_WBW) ; | | | + #if (CPUFAM == CPU_Z180) ; | | | + or a ; +4ts for z180 | | | + #endif ; | | | +#endif ; | | | + dec a ; 4ts | | | + jr nz,vdelay1 ; 12ts (nz) / 7ts (z) | | | + ; ----------------------------------------------+ | | +; | | + dec de ; 6ts | | +#if (BIOS == BIOS_WBW) ; | | | + #if (CPUFAM == CPU_Z180) ; | | + or a ; +4ts for z180 | | + #endif ; | | +#endif ; | | + ld a,d ; 4ts | | + or e ; 4ts | | + jp nz,vdelay ; 10ts | | + ;-------------------------------------------------------+ | +; | + ret ; 10ts (final return) | + ;---------------------------------------------------------------+ +; +; Delay about 0.5 seconds +; 500000us / 16us = 31250 +; +ldelay: + push af + push de + ld de,31250 + call vdelay + pop de + pop af + ret +; +; Initialize delay scaler based on operating cpu speed +; HBIOS *must* be installed and available via rst 8!!! +; CPU scaler := max(1, (phimhz - 2)) +; +delay_init: +#if (BIOS == BIOS_UNA) + ld c,$F8 ; UNA bios get phi function + rst 08 ; returns speed in hz in de:hl + ld b,4 ; divide mhz in de:hl by 100000h +delay_init0: + srl d ; ... to get approx cpu speed in + rr e ; ...mhz. throw away hl, and + djnz delay_init0 ; ...right shift de by 4. + inc e ; fix up for value truncation + ld a,e ; put in a +#else + ld b,BF_SYSGET ; HBIOS func=get sys info + ld c,BF_SYSGET_CPUINFO ; HBIOS subfunc=get cpu info + rst 08 ; call HBIOS, rst 08 not yet installed + ld a,l ; put speed in mhz in accum +#endif + cp 3 ; test for <= 2 (special handling) + jr c,delay_init1 ; if <= 2, special processing + sub 2 ; adjust as required by delay functions + jr delay_init2 ; and continue +delay_init1: + ld a,1 ; use the min value of 1 +delay_init2: + ld (cpuscl),a ; update cpu scaler value + ret + +#if (CPUMHZ < 3) +cpuscl .db 1 ; cpu scaler must be > 0 +#else +cpuscl .db CPUMHZ - 2 ; otherwise 2 less than phi mhz +#endif +; +; 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 +; +; Short delay functions. No clock speed compensation, so they +; will run longer on slower systems. The number indicates the +; number of call/ret invocations. A single call/ret is +; 27 t-states on a z80, 25 t-states on a z180. +; +; ; z80 z180 +; ; ---- ---- +dly64: call dly32 ; 1728 1600 +dly32: call dly16 ; 864 800 +dly16: call dly8 ; 432 400 +dly8: call dly4 ; 216 200 +dly4: call dly2 ; 108 100 +dly2: call dly1 ; 54 50 +dly1: ret ; 27 25 +; +; Add hl,a +; +; A register is destroyed! +; +addhla: + add a,l + ld l,a + ret nc + inc h + ret +; +; Print the hex byte value in A +; +prthexbyte: + push af + push de + call hexascii + ld a,d + call cout + ld a,e + call cout + pop de + pop af + ret +; +; Print the hex word value in BC +; +prthexword: + push af + ld a,b + call prthexbyte + ld a,c + call prthexbyte + pop af + ret +; +; Print the hex dword value in DE:HL +; +prthex32: + push bc + push de + pop bc + call prthexword + push hl + pop bc + call prthexword + pop bc + ret +; +; Convert binary value in A to ASCII hex characters in DE +; +hexascii: + ld d,a + call hexconv + ld e,a + ld a,d + rlca + rlca + rlca + rlca + call hexconv + ld d,a + ret +; +; Convert low nibble of A to ASCII hex +; +hexconv: + and 0Fh ; low nibble only + add a,90h + daa + adc a,40h + daa + ret +; ;======================================================================= ; Console character I/O helper routines (registers preserved) ;======================================================================= @@ -1241,7 +1565,7 @@ prtall1: ld hl,str_disk ; prefix string call pstr ; display it ld a,c ; index - call PRTDECB ; print it + call prtdecb ; print it ld hl,str_on ; separator string call pstr push bc ; save loop control @@ -1268,7 +1592,7 @@ prtdrv: and $0F ; isolate device bits add a,a ; multiple by two for word table ld hl,devtbl ; point to start of table - call ADDHLA ; add A to HL for table entry + call addhla ; add A to HL for table entry ld a,(hl) ; deref HL for string adr inc hl ; ... ld h,(hl) ; ... @@ -1277,7 +1601,7 @@ prtdrv: pop hl ; recover HL pop de ; recover DE ld a,e ; device number - call PRTDECB ; print it + call prtdecb ; print it ld a,':' ; suffix call cout ; print it ret @@ -1340,7 +1664,7 @@ prtdrv: ld hl,str_disk ; prefix string call pstr ; display it ld a,b ; index - call PRTDECB ; print it + call prtdecb ; print it ld a,' ' ; formatting call cout ; do it ld a,'=' ; formatting @@ -1380,7 +1704,7 @@ prtdrv2: ; print device pop bc ; recover unit call pstr ; print device name ld a,b ; unit to a - call PRTDECB ; print it + call prtdecb ; print it ld a,':' ; device name suffix call cout ; print it ret ; done @@ -1452,10 +1776,12 @@ str_err_api .db "Unexpected hardware BIOS API failure",0 ;======================================================================= ; #define USEDELAY -#include "util.asm" +; #include "util.asm" ; #if (DSKYENABLE) #define DSKY_KBD +VDELAY .equ vdelay +DLY2 .equ dly2 #include "dsky.asm" #endif ; @@ -1492,6 +1818,7 @@ str_binfo2 .db $22," [0x",0 str_binfo3 .db "-0x",0 str_binfo4 .db ", entry @ 0x",0 str_binfo5 .db "]",0 +str_ldsec .db ", Sector 0x",0 ; str_help .db "\r\n" .db "\r\n L - List ROM Applications" @@ -1651,9 +1978,12 @@ bid_ldr .ds 1 ; bank at startup #endif #if (BIOS == BIOS_UNA) bid_ldr .ds 2 ; bank at startup -loadlba .ds 4 ; lba for load, dword #endif ; +lba .ds 4 ; lba for load, dword +dma .ds 2 ; address for load +sps .ds 2 ; sectors per slice +; ra_tbl_loc .ds 2 ; points to active ra_tbl bootunit .ds 1 ; boot disk unit bootslice .ds 1 ; boot disk slice @@ -1685,5 +2015,11 @@ 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) +; +; +; Master Boot Record sector is read into area below. +; +bl_mbrsec .equ $ + .ds 512 ; .end diff --git a/Source/Images/Build.cmd b/Source/Images/Build.cmd index 2305cc74..c33d9604 100644 --- a/Source/Images/Build.cmd +++ b/Source/Images/Build.cmd @@ -4,24 +4,24 @@ setlocal echo. echo Building Floppy Disk Images... echo. -call BuildFD.cmd cpm22 ..\cpm22\cpm_wbw.sys -call BuildFD.cmd zsdos ..\zsdos\zsys_wbw.sys -call BuildFD.cmd nzcom ..\zsdos\zsys_wbw.sys -call BuildFD.cmd cpm3 ..\cpm3\cpmldr.sys -call BuildFD.cmd zpm3 ..\cpm3\cpmldr.sys -call BuildFD.cmd ws4 +call BuildFD.cmd cpm22 wbw_fd144 ..\cpm22\cpm_wbw.sys +call BuildFD.cmd zsdos wbw_fd144 ..\zsdos\zsys_wbw.sys +call BuildFD.cmd nzcom wbw_fd144 ..\zsdos\zsys_wbw.sys +call BuildFD.cmd cpm3 wbw_fd144 ..\cpm3\cpmldr.sys +call BuildFD.cmd zpm3 wbw_fd144 ..\cpm3\cpmldr.sys +call BuildFD.cmd ws4 wbw_fd144 echo. echo Building Hard Disk Images... echo. -call BuildHD.cmd cpm22 ..\cpm22\cpm_wbw.sys -call BuildHD.cmd zsdos ..\zsdos\zsys_wbw.sys -call BuildHD.cmd nzcom ..\zsdos\zsys_wbw.sys -call BuildHD.cmd cpm3 ..\cpm3\cpmldr.sys -call BuildHD.cmd zpm3 ..\cpm3\cpmldr.sys -call BuildHD.cmd ws4 +call BuildHD.cmd cpm22 wbw_hd0 ..\cpm22\cpm_wbw.sys +call BuildHD.cmd zsdos wbw_hd0 ..\zsdos\zsys_wbw.sys +call BuildHD.cmd nzcom wbw_hd0 ..\zsdos\zsys_wbw.sys +call BuildHD.cmd cpm3 wbw_hd0 ..\cpm3\cpmldr.sys +call BuildHD.cmd zpm3 wbw_hd0 ..\cpm3\cpmldr.sys +call BuildHD.cmd ws4 wbw_hd0 -if exist ..\BPBIOS\bpbio-ww.rel call BuildHD.cmd bp +if exist ..\BPBIOS\bpbio-ww.rel call BuildHD.cmd bp wbw_hd echo. echo Building Combo Disk Image... diff --git a/Source/Images/BuildFD.ps1 b/Source/Images/BuildFD.ps1 index f482bc10..f1c0d25d 100644 --- a/Source/Images/BuildFD.ps1 +++ b/Source/Images/BuildFD.ps1 @@ -1,10 +1,9 @@ -#Param([Parameter(Mandatory)]$Disk, $SysFile="") -Param($Disk, $SysFile="") +Param($Disk, $Format="wbw_fd144", $SysFile="") $ErrorAction = 'Stop' $ImgFile = "fd_${Disk}.img" -$Fmt = "wbw_fd144" +$MediaID = 6 $Size = 1440KB $CpmToolsPath = '../../Tools/cpmtools' @@ -13,35 +12,31 @@ $env:PATH = $CpmToolsPath + ';' + $env:PATH if (-not (Test-Path("d_${Disk}/"))) { - "Source directory d_${Disk} for disk ${Disk} not found!" + Write-Error "Source directory d_${Disk} for disk ${Disk} not found!" -ErrorAction Stop return } "Generating Floppy Disk ${Disk}..." -#$Blank = ([string]([char]0xE5)) * $Size -#Set-Content -Value $Blank -NoNewLine -Path $ImgFile -$Blank = ([byte[]](0xE5) * $Size) -[System.IO.File]::WriteAllBytes($ImgFile, $Blank) +if ($SysFile.Length -gt 0) + { [byte[]]$SysImg = [System.IO.File]::ReadAllBytes($SysFile) } +else + { [byte[]]$SysImg = @() } -if ($SysFile.Length -gt 0) -{ - "Adding System Image $SysFile..." - #$Sys = Get-Content -Path "$SysFile.sys" -Raw - #$Img = Get-Content -Path $ImgFile -Raw - #$NewImg = $Sys + $Img.SubString($Sys.Length, $Img.Length - $Sys.Length) - #Set-Content -NoNewLine -Path $ImgFile $NewImg - - $Cmd = "mkfs.cpm -f $Fmt -b $SysFile $ImgFile" - $Cmd - Invoke-Expression $Cmd -} +$Image = ($SysImg + ([byte[]](0xE5) * ($Size - $SysImg.length))) + +$Image[1410] = 0x4D +$Image[1411] = 0x49 +$Image[1412] = 0x44 +$Image[1413] = $MediaID + +[System.IO.File]::WriteAllBytes($ImgFile, $Image) for ($Usr=0; $Usr -lt 16; $Usr++) { if (Test-Path ("d_${Disk}/u${Usr}/*")) { - $Cmd = "cpmcp -f $Fmt $ImgFile d_${Disk}/u${Usr}/*.* ${Usr}:" + $Cmd = "cpmcp -f $Format $ImgFile d_${Disk}/u${Usr}/*.* ${Usr}:" $Cmd Invoke-Expression $Cmd } @@ -54,7 +49,7 @@ if (Test-Path("d_${Disk}.txt")) $Spec = $Line.Trim() if (($Spec.Length -gt 0) -and ($Spec.Substring(0,1) -ne "#")) { - $Cmd = "cpmcp -f $Fmt $ImgFile ${Spec}" + $Cmd = "cpmcp -f $Format $ImgFile ${Spec}" $Cmd Invoke-Expression $Cmd } @@ -63,7 +58,6 @@ if (Test-Path("d_${Disk}.txt")) "Moving image $ImgFile into output directory..." -#&$env:COMSPEC /c move $ImgFile ..\..\Binary\ Move-Item $ImgFile -Destination "..\..\Binary\" -Force return \ No newline at end of file diff --git a/Source/Images/BuildHD.ps1 b/Source/Images/BuildHD.ps1 index eedfa4aa..525e2d4a 100644 --- a/Source/Images/BuildHD.ps1 +++ b/Source/Images/BuildHD.ps1 @@ -1,11 +1,21 @@ -#Param([Parameter(Mandatory)]$Disk, $SysFile="") -Param($Disk, $SysFile="") +Param($Disk, $Format="wbw_hd_new", $SysFile="") $ErrorAction = 'Stop' -$ImgFile = "hd_${Disk}.img" -$Fmt = "wbw_hd0" -$Size = (128KB * 65) +if ($Format -like "*_new") +{ + # New hard disk format!!! + $MediaID = 10 + $Size = 8 * 1MB + $ImgFile = "hd_${Disk}.bin" +} +else +{ + # Legacy hard disk format + $MediaID = 4 + $Size = 8320KB + $ImgFile = "hd_${Disk}.img" +} $CpmToolsPath = '../../Tools/cpmtools' @@ -13,35 +23,31 @@ $env:PATH = $CpmToolsPath + ';' + $env:PATH if (-not (Test-Path("d_${Disk}/"))) { - "Source directory d_${Disk} for disk ${Disk} not found!" + Write-Error "Source directory d_${Disk} for disk ${Disk} not found!" -ErrorAction Stop return } "Generating Hard Disk ${Disk}..." -#$Blank = ([string]([char]0xE5)) * $Size -#Set-Content -Value $Blank -NoNewLine -Path $ImgFile -$Blank = ([byte[]](0xE5) * $Size) -[System.IO.File]::WriteAllBytes($ImgFile, $Blank) +if ($SysFile.Length -gt 0) + { [byte[]]$SysImg = [System.IO.File]::ReadAllBytes($SysFile) } +else + { [byte[]]$SysImg = @() } -if ($SysFile.Length -gt 0) -{ - "Adding System Image $SysFile..." - #$Sys = Get-Content -Path "$SysFile.sys" -Raw - #$Img = Get-Content -Path $ImgFile -Raw - #$NewImg = $Sys + $Img.SubString($Sys.Length, $Img.Length - $Sys.Length) - #Set-Content -NoNewLine -Path $ImgFile $NewImg - - $Cmd = "mkfs.cpm -f $Fmt -b $SysFile $ImgFile" - $Cmd - Invoke-Expression $Cmd -} +$Image = ($SysImg + ([byte[]](0xE5) * ($Size - $SysImg.length))) + +$Image[1410] = 0x4D +$Image[1411] = 0x49 +$Image[1412] = 0x44 +$Image[1413] = $MediaID + +[System.IO.File]::WriteAllBytes($ImgFile, $Image) for ($Usr=0; $Usr -lt 16; $Usr++) { if (Test-Path ("d_${Disk}/u${Usr}/*")) { - $Cmd = "cpmcp -f $Fmt $ImgFile d_${Disk}/u${Usr}/*.* ${Usr}:" + $Cmd = "cpmcp -f $Format $ImgFile d_${Disk}/u${Usr}/*.* ${Usr}:" $Cmd Invoke-Expression $Cmd } @@ -54,7 +60,7 @@ if (Test-Path("d_${Disk}.txt")) $Spec = $Line.Trim() if (($Spec.Length -gt 0) -and ($Spec.Substring(0,1) -ne "#")) { - $Cmd = "cpmcp -f $Fmt $ImgFile ${Spec}" + $Cmd = "cpmcp -f $Format $ImgFile ${Spec}" $Cmd Invoke-Expression $Cmd } @@ -63,7 +69,6 @@ if (Test-Path("d_${Disk}.txt")) "Moving image $ImgFile into output directory..." -#&$env:COMSPEC /c move $ImgFile ..\..\Binary\ Move-Item $ImgFile -Destination "..\..\Binary\" -Force return \ No newline at end of file diff --git a/Source/Images/BuildNew.cmd b/Source/Images/BuildNew.cmd new file mode 100644 index 00000000..eb1b0174 --- /dev/null +++ b/Source/Images/BuildNew.cmd @@ -0,0 +1,40 @@ +@echo off +setlocal + +echo. +echo Building Floppy Disk Images... +echo. +call BuildFD.cmd cpm22 wbw_fd144 ..\cpm22\cpm_wbw.sys +call BuildFD.cmd zsdos wbw_fd144 ..\zsdos\zsys_wbw.sys +call BuildFD.cmd nzcom wbw_fd144 ..\zsdos\zsys_wbw.sys +call BuildFD.cmd cpm3 wbw_fd144 ..\cpm3\cpmldr.sys +call BuildFD.cmd zpm3 wbw_fd144 ..\cpm3\cpmldr.sys +call BuildFD.cmd ws4 wbw_fd144 + +echo. +echo Building Hard Disk Images... +echo. +call BuildHD.cmd cpm22 wbw_hd_new ..\cpm22\cpm_wbw.sys +call BuildHD.cmd zsdos wbw_hd_new ..\zsdos\zsys_wbw.sys +call BuildHD.cmd nzcom wbw_hd_new ..\zsdos\zsys_wbw.sys +call BuildHD.cmd cpm3 wbw_hd_new ..\cpm3\cpmldr.sys +call BuildHD.cmd zpm3 wbw_hd_new ..\cpm3\cpmldr.sys +call BuildHD.cmd ws4 wbw_hd_new + +if exist ..\BPBIOS\bpbio-ww.rel call BuildHD.cmd bp wbw_hd_new + +copy hd_prefix.dat ..\..\Binary\ + +echo. +echo Build Hard Disk Images... +copy /b hd_prefix.dat + ..\..\Binary\hd_cpm22.bin ..\..\Binary\hd_cpm22.img +copy /b hd_prefix.dat + ..\..\Binary\hd_zsdos.bin ..\..\Binary\hd_zsdos.img +copy /b hd_prefix.dat + ..\..\Binary\hd_nzcom.bin ..\..\Binary\hd_nzcom.img +copy /b hd_prefix.dat + ..\..\Binary\hd_cpm3.bin ..\..\Binary\hd_cpm3.img +copy /b hd_prefix.dat + ..\..\Binary\hd_zpm3.bin ..\..\Binary\hd_zpm3.img +copy /b hd_prefix.dat + ..\..\Binary\hd_ws4.bin ..\..\Binary\hd_ws4.img +if exist ..\..\Binary\hd_bp.bin copy /b hd_prefix.dat + ..\..\Binary\hd_bp.bin + +echo. +echo Building Combo Disk Image... +copy /b hd_prefix.dat + ..\..\Binary\hd_cpm22.bin + ..\..\Binary\hd_zsdos.bin + ..\..\Binary\hd_nzcom.bin + ..\..\Binary\hd_cpm3.bin + ..\..\Binary\hd_zpm3.bin + ..\..\Binary\hd_ws4.bin ..\..\Binary\hd_combo.img diff --git a/Source/Images/Makefile b/Source/Images/Makefile index 4832dc37..13fbbdb0 100644 --- a/Source/Images/Makefile +++ b/Source/Images/Makefile @@ -5,12 +5,22 @@ SYSTEMS = ../CPM22/cpm_wbw.sys ../ZSDOS/zsys_wbw.sys ../CPM3/cpmldr.sys FDIMGS = fd_cpm22.img fd_zsdos.img fd_nzcom.img \ fd_cpm3.img fd_zpm3.img fd_ws4.img +FDBIN = fd_cpm22.bin fd_zsdos.bin fd_nzcom.bin \ + fd_cpm3.bin fd_zpm3.bin fd_ws4.bin HDIMGS = hd_cpm22.img hd_zsdos.img hd_nzcom.img \ hd_cpm3.img hd_zpm3.img hd_ws4.img +HDBIN = hd_cpm22.bin hd_zsdos.bin hd_nzcom.bin \ + hd_cpm3.bin hd_zpm3.bin hd_ws4.bin # HDIMGS += hd_bp.img +# HDBIN += hd_bp.bin -OBJECTS = $(FDIMGS) $(HDIMGS) hd_combo.img -OTHERS = blank144 blankhd +HDPREFIX = # Legacy +#HDPREFIX = hd_prefix.dat # New + +OBJECTS = $(FDIMGS) $(HDIMGS) hd_combo.img # Legacy +#OBJECTS = $(FDIMGS) $(HDIMGS) $(HDBIN) hd_combo.img # New + +OTHERS = blank144 blankhd $(FDBIN) $(HDBIN) DEST=../../Binary @@ -19,8 +29,8 @@ include $(TOOLS)/Makefile.inc DIFFPATH = $(DIFFTO)/Binary -hd_combo.img: $(HDIMGS) - cat $(HDIMGS) > $@ +hd_combo.img: $(HDPREFIX) $(HDBIN) + cat $^ > $@ # # this somewhat impenetrable and fragile code is used to build each of the images @@ -30,17 +40,28 @@ hd_combo.img: $(HDIMGS) # then process the d_{d}.txt file, copying in those files, and finally maybe put # an OS at the start of each image # + +FDSIZE := 1440 + blank144: - @echo Making Blank Floppy of size 1440k - @LANG=en_US.US-ASCII tr '\000' '\345' /dev/null + @echo Making Blank Floppy of size $(FDSIZE)k + @LC_CTYPE=en_US.US-ASCII tr '\000' '\345' /dev/null -HDSIZE := $(shell expr 128 '*' 65) +HDSIZE := 8320 # Legacy +#HDSIZE := 8192 # New blankhd: @echo Making Blank Hd of size $(HDSIZE)k - @LANG=en_US.US-ASCII tr '\000' '\345' /dev/null + @LC_CTYPE=en_US.US-ASCII tr '\000' '\345' /dev/null + +%.img: %.bin + @if echo $@ | grep -q ^f ; then \ + cat $< > $@ ; \ + else \ + cat $(HDPREFIX) $< > $@ ; \ + fi ; \ -%.img: $(SYSTEMS) blank144 blankhd Makefile +%.bin: $(SYSTEMS) blank144 blankhd Makefile @sys= ; \ case $@ in \ (*cpm22*) sys=../CPM22/cpm_wbw.sys;; \ @@ -49,8 +70,12 @@ blankhd: esac ; \ if echo $@ | grep -q ^f ; then \ fmt=wbw_fd144 ; type=fd_ ; proto=blank144 ; \ + mid="MID\006" ; \ else \ + #fmt=wbw_hd_new ; type=hd_ ; proto=blankhd ; \ + #mid="MID\012" ; \ fmt=wbw_hd0 ; type=hd_ ; proto=blankhd ; \ + mid="MID\004" ; \ fi ; \ d=$$(echo $(basename $@) | sed s/$$type//) ; \ echo Generating $@ ; \ @@ -59,6 +84,7 @@ blankhd: echo copying system $$sys to $@ ; \ $(BINDIR)/mkfs.cpm -f $$fmt -b $$sys $@ ; \ fi ; \ + LC_CTYPE=en_US.US-ASCII echo $$mid | dd bs=1 count=4 seek=1410 conv=notrunc of=$@ ; \ for u in $$(seq 0 15) ; do \ dir=d_$$d/u$$u ; \ if [ -d $$dir ] ; then \ @@ -93,7 +119,7 @@ imgdiff: if echo $$i | grep -q ^f ; then \ fmt=wbw_fd144 ; \ else \ - fmt=wbw_hd0 ; \ + fmt=wbw_hd0_1024 ; \ fi ; \ $(BINDIR)/cpmls -i -f $$fmt $$i > $$i.ls ; \ $(BINDIR)/cpmls -i -f $$fmt $(DIFFPATH)/$$i > $$i.diff.ls ; \ diff --git a/Source/Images/diskdefs b/Source/Images/diskdefs index 937bfcf2..dad4c46e 100644 --- a/Source/Images/diskdefs +++ b/Source/Images/diskdefs @@ -297,121 +297,158 @@ diskdef wbw_rom1024 os 2.2 end -# UNA 512KB ROM (128KB reserved, 384KB ROM Disk) +# RomWBW 720K floppy media +diskdef wbw_fd720 + seclen 512 + tracks 160 + sectrk 9 + blocksize 2048 + maxdir 128 + skew 0 + boottrk 4 + os 2.2 +end -diskdef una_rom512 +# RomWBW 1.44M floppy media +diskdef wbw_fd144 seclen 512 - tracks 12 - sectrk 64 + tracks 160 + sectrk 18 blocksize 2048 maxdir 256 skew 0 - boottrk 0 + boottrk 2 os 2.2 end -# UNA 512KB ROM (128KB reserved, 896KB ROM Disk) +# RomWBW 360K floppy media +diskdef wbw_fd360 + seclen 512 + tracks 80 + sectrk 9 + blocksize 2048 + maxdir 128 + skew 0 + boottrk 4 + os 2.2 +end -diskdef una_rom1024 +# RomWBW 1.20M floppy media +diskdef wbw_fd120 seclen 512 - tracks 28 - sectrk 64 + tracks 160 + sectrk 15 blocksize 2048 maxdir 256 skew 0 - boottrk 0 + boottrk 2 os 2.2 end -# RomWBW 8MB Hard Disk, LU 0-3 +# RomWBW 8MB Hard Disk, first 4 slices +# Legacy format, 512 dir entries, 8,320 sectors / slice diskdef wbw_hd0 seclen 512 - tracks 65 - sectrk 256 + tracks 1040 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 1 + boottrk 16 os 2.2 end diskdef wbw_hd1 seclen 512 - tracks 130 - sectrk 256 + tracks 2080 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 66 + boottrk 1056 os 2.2 end diskdef wbw_hd2 seclen 512 - tracks 195 - sectrk 256 + tracks 3120 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 131 + boottrk 2096 os 2.2 end diskdef wbw_hd3 seclen 512 - tracks 260 - sectrk 256 + tracks 4160 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 196 + boottrk 3136 os 2.2 end -# RomWBW 720K floppy media -diskdef wbw_fd720 + +# RomWBW 8MB Hard Disk +# New format, 1024 dir entries, 8,192 sectors / slice +# Pure filesystem image, no prefix +diskdef wbw_hd_new seclen 512 - tracks 160 - sectrk 9 - blocksize 2048 - maxdir 128 + tracks 1024 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 4 + boottrk 2 os 2.2 end -# RomWBW 1.44M floppy media -diskdef wbw_fd144 +# RomWBW 8MB Hard Disk, first 4 slices +# New format, 1024 dir entries, 8,192 sectors / slice +# Assumes 256 sector (16 track) hard disk prefix +diskdef wbw_hd0_new seclen 512 - tracks 160 - sectrk 18 - blocksize 2048 - maxdir 256 + tracks 1040 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 2 + boottrk 18 os 2.2 end -# RomWBW 360K floppy media -diskdef wbw_fd360 +diskdef wbw_hd1_new seclen 512 - tracks 80 - sectrk 9 - blocksize 2048 - maxdir 128 + tracks 2064 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 4 + boottrk 1042 os 2.2 end -# RomWBW 1.20M floppy media -diskdef wbw_fd120 +diskdef wbw_hd2_new seclen 512 - tracks 160 - sectrk 15 - blocksize 2048 - maxdir 256 + tracks 3112 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 2 + boottrk 2066 + os 2.2 +end + +diskdef wbw_hd3_new + seclen 512 + tracks 4136 + sectrk 16 + blocksize 4096 + maxdir 1024 + skew 0 + boottrk 3114 os 2.2 end diff --git a/Source/Images/hd_prefix.dat b/Source/Images/hd_prefix.dat new file mode 100644 index 00000000..3248248d Binary files /dev/null and b/Source/Images/hd_prefix.dat differ diff --git a/Source/ver.inc b/Source/ver.inc index 40ef4218..f5695008 100644 --- a/Source/ver.inc +++ b/Source/ver.inc @@ -1,5 +1,5 @@ #DEFINE RMJ 3 #DEFINE RMN 1 -#DEFINE RUP 0 +#DEFINE RUP 1 #DEFINE RTP 0 -#DEFINE BIOSVER "3.1-pre.16" +#DEFINE BIOSVER "3.1.1-pre.0" diff --git a/Source/ver.lib b/Source/ver.lib index b1f8589d..37b9c82d 100644 --- a/Source/ver.lib +++ b/Source/ver.lib @@ -1,7 +1,7 @@ rmj equ 3 rmn equ 1 -rup equ 0 +rup equ 1 rtp equ 0 biosver macro - db "3.1-pre.16" + db "3.1.1-pre.0" endm diff --git a/Tools/cpmtools/diskdefs b/Tools/cpmtools/diskdefs index 937bfcf2..dad4c46e 100644 --- a/Tools/cpmtools/diskdefs +++ b/Tools/cpmtools/diskdefs @@ -297,121 +297,158 @@ diskdef wbw_rom1024 os 2.2 end -# UNA 512KB ROM (128KB reserved, 384KB ROM Disk) +# RomWBW 720K floppy media +diskdef wbw_fd720 + seclen 512 + tracks 160 + sectrk 9 + blocksize 2048 + maxdir 128 + skew 0 + boottrk 4 + os 2.2 +end -diskdef una_rom512 +# RomWBW 1.44M floppy media +diskdef wbw_fd144 seclen 512 - tracks 12 - sectrk 64 + tracks 160 + sectrk 18 blocksize 2048 maxdir 256 skew 0 - boottrk 0 + boottrk 2 os 2.2 end -# UNA 512KB ROM (128KB reserved, 896KB ROM Disk) +# RomWBW 360K floppy media +diskdef wbw_fd360 + seclen 512 + tracks 80 + sectrk 9 + blocksize 2048 + maxdir 128 + skew 0 + boottrk 4 + os 2.2 +end -diskdef una_rom1024 +# RomWBW 1.20M floppy media +diskdef wbw_fd120 seclen 512 - tracks 28 - sectrk 64 + tracks 160 + sectrk 15 blocksize 2048 maxdir 256 skew 0 - boottrk 0 + boottrk 2 os 2.2 end -# RomWBW 8MB Hard Disk, LU 0-3 +# RomWBW 8MB Hard Disk, first 4 slices +# Legacy format, 512 dir entries, 8,320 sectors / slice diskdef wbw_hd0 seclen 512 - tracks 65 - sectrk 256 + tracks 1040 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 1 + boottrk 16 os 2.2 end diskdef wbw_hd1 seclen 512 - tracks 130 - sectrk 256 + tracks 2080 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 66 + boottrk 1056 os 2.2 end diskdef wbw_hd2 seclen 512 - tracks 195 - sectrk 256 + tracks 3120 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 131 + boottrk 2096 os 2.2 end diskdef wbw_hd3 seclen 512 - tracks 260 - sectrk 256 + tracks 4160 + sectrk 16 blocksize 4096 maxdir 512 skew 0 - boottrk 196 + boottrk 3136 os 2.2 end -# RomWBW 720K floppy media -diskdef wbw_fd720 + +# RomWBW 8MB Hard Disk +# New format, 1024 dir entries, 8,192 sectors / slice +# Pure filesystem image, no prefix +diskdef wbw_hd_new seclen 512 - tracks 160 - sectrk 9 - blocksize 2048 - maxdir 128 + tracks 1024 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 4 + boottrk 2 os 2.2 end -# RomWBW 1.44M floppy media -diskdef wbw_fd144 +# RomWBW 8MB Hard Disk, first 4 slices +# New format, 1024 dir entries, 8,192 sectors / slice +# Assumes 256 sector (16 track) hard disk prefix +diskdef wbw_hd0_new seclen 512 - tracks 160 - sectrk 18 - blocksize 2048 - maxdir 256 + tracks 1040 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 2 + boottrk 18 os 2.2 end -# RomWBW 360K floppy media -diskdef wbw_fd360 +diskdef wbw_hd1_new seclen 512 - tracks 80 - sectrk 9 - blocksize 2048 - maxdir 128 + tracks 2064 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 4 + boottrk 1042 os 2.2 end -# RomWBW 1.20M floppy media -diskdef wbw_fd120 +diskdef wbw_hd2_new seclen 512 - tracks 160 - sectrk 15 - blocksize 2048 - maxdir 256 + tracks 3112 + sectrk 16 + blocksize 4096 + maxdir 1024 skew 0 - boottrk 2 + boottrk 2066 + os 2.2 +end + +diskdef wbw_hd3_new + seclen 512 + tracks 4136 + sectrk 16 + blocksize 4096 + maxdir 1024 + skew 0 + boottrk 3114 os 2.2 end