Browse Source

Early partition table support

Adding infrastructure for partition table support.  Backward compatible.  Not ready for end user usage yet.

Bumped version to 3.1.1 to demarcate this change.
pull/123/head
Wayne Warthen 6 years ago
parent
commit
ee0fac37f9
  1. 1
      Binary/Clean.cmd
  2. 5
      Doc/ChangeLog.txt
  3. 10
      Source/Apps/Assign.asm
  4. 12
      Source/Apps/Timer.asm
  5. 139
      Source/BPBIOS/diskdefs
  6. 277
      Source/CBIOS/cbios.asm
  7. 12
      Source/CBIOS/util.asm
  8. 442
      Source/CPM3/biosldr.z80
  9. 2
      Source/CPM3/boot.z80
  10. 482
      Source/CPM3/diskio.z80
  11. 4
      Source/CPM3/genbnk.dat
  12. 3
      Source/CPM3/move.z80
  13. 3
      Source/CPM3/optzpm.lib
  14. 2
      Source/CPM3/util.z80
  15. 139
      Source/HBIOS/diskdefs
  16. 548
      Source/HBIOS/romldr.asm
  17. 26
      Source/Images/Build.cmd
  18. 38
      Source/Images/BuildFD.ps1
  19. 53
      Source/Images/BuildHD.ps1
  20. 40
      Source/Images/BuildNew.cmd
  21. 46
      Source/Images/Makefile
  22. 139
      Source/Images/diskdefs
  23. BIN
      Source/Images/hd_prefix.dat
  24. 4
      Source/ver.inc
  25. 4
      Source/ver.lib
  26. 139
      Tools/cpmtools/diskdefs

1
Binary/Clean.cmd

@ -2,6 +2,7 @@
setlocal setlocal
if exist *.bin del *.bin if exist *.bin del *.bin
if exist *.dat del *.dat
if exist *.com del *.com if exist *.com del *.com
if exist *.img del *.img if exist *.img del *.img
if exist *.rom del *.rom if exist *.rom del *.rom

5
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 Version 3.1
----------- -----------
- WBW: Refactored ROM Loader - WBW: Refactored ROM Loader

10
Source/Apps/Assign.asm

@ -22,7 +22,8 @@
; 2016-04-08 [WBW] Determine key memory addresses dynamically ; 2016-04-08 [WBW] Determine key memory addresses dynamically
; 2019-08-07 [WBW] Fixed DPB selection error ; 2019-08-07 [WBW] Fixed DPB selection error
; 2019-11-17 [WBW] Added preliminary CP/M 3 support ; 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: ; ToDo:
@ -546,7 +547,8 @@ dph_init2:
ld a,(hl) ; unit to A ld a,(hl) ; unit to A
push bc ; save loop control push bc ; save loop control
push hl ; save drive map pointer 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 call alloc ; allocate space for dph
jp c,instovf ; handle overflow error jp c,instovf ; handle overflow error
push hl ; save DPH location push hl ; save DPH location
@ -1866,10 +1868,10 @@ stack .equ $ ; stack top
; Messages ; Messages
; ;
indent .db " ",0 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 msghb .db " (HBIOS Mode)",0
msgub .db " (UBIOS 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:|<device>[<unitnum>]:[<slicenum>]}]][,...]",13,10 msguse .db "Usage: ASSIGN D:[=[{D:|<device>[<unitnum>]:[<slicenum>]}]][,...]",13,10
.db " ex. ASSIGN (display all active assignments)",13,10 .db " ex. ASSIGN (display all active assignments)",13,10
.db " ASSIGN /? (display version and usage)",13,10 .db " ASSIGN /? (display version and usage)",13,10

12
Source/Apps/Timer.asm

@ -41,8 +41,11 @@ rmn .equ 1 ; intended CBIOS version - minor
; ;
bf_sysver .equ $F1 ; BIOS: VER function bf_sysver .equ $F1 ; BIOS: VER function
bf_sysget .equ $F8 ; HBIOS: SYSGET function bf_sysget .equ $F8 ; HBIOS: SYSGET function
bf_sysset .equ $F9 ; HBIOS: SYSGET function
bf_sysgettimer .equ $D0 ; TIMER subfunction bf_sysgettimer .equ $D0 ; TIMER subfunction
bf_syssettimer .equ $D0 ; TIMER subfunction
bf_sysgetsecs .equ $D1 ; SECONDS subfunction bf_sysgetsecs .equ $D1 ; SECONDS subfunction
bf_syssetsecs .equ $D1 ; SECONDS subfunction
; ;
;=============================================================================== ;===============================================================================
; Code Section ; Code Section
@ -106,6 +109,15 @@ process00:
jr process00 ; continue looking for options jr process00 ; continue looking for options
; ;
process0: 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 call crlf2 ; formatting
; ;
process1: process1:

139
Source/BPBIOS/diskdefs

@ -297,121 +297,158 @@ diskdef wbw_rom1024
os 2.2 os 2.2
end 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 seclen 512
tracks 12
sectrk 64
tracks 160
sectrk 18
blocksize 2048 blocksize 2048
maxdir 256 maxdir 256
skew 0 skew 0
boottrk 0
boottrk 2
os 2.2 os 2.2
end 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 seclen 512
tracks 28
sectrk 64
tracks 160
sectrk 15
blocksize 2048 blocksize 2048
maxdir 256 maxdir 256
skew 0 skew 0
boottrk 0
boottrk 2
os 2.2 os 2.2
end 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 diskdef wbw_hd0
seclen 512 seclen 512
tracks 65
sectrk 256
tracks 1040
sectrk 16
blocksize 4096 blocksize 4096
maxdir 512 maxdir 512
skew 0 skew 0
boottrk 1
boottrk 16
os 2.2 os 2.2
end end
diskdef wbw_hd1 diskdef wbw_hd1
seclen 512 seclen 512
tracks 130
sectrk 256
tracks 2080
sectrk 16
blocksize 4096 blocksize 4096
maxdir 512 maxdir 512
skew 0 skew 0
boottrk 66
boottrk 1056
os 2.2 os 2.2
end end
diskdef wbw_hd2 diskdef wbw_hd2
seclen 512 seclen 512
tracks 195
sectrk 256
tracks 3120
sectrk 16
blocksize 4096 blocksize 4096
maxdir 512 maxdir 512
skew 0 skew 0
boottrk 131
boottrk 2096
os 2.2 os 2.2
end end
diskdef wbw_hd3 diskdef wbw_hd3
seclen 512 seclen 512
tracks 260
sectrk 256
tracks 4160
sectrk 16
blocksize 4096 blocksize 4096
maxdir 512 maxdir 512
skew 0 skew 0
boottrk 196
boottrk 3136
os 2.2 os 2.2
end 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 seclen 512
tracks 160
sectrk 9
blocksize 2048
maxdir 128
tracks 1024
sectrk 16
blocksize 4096
maxdir 1024
skew 0 skew 0
boottrk 4
boottrk 2
os 2.2 os 2.2
end 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 seclen 512
tracks 160
sectrk 18
blocksize 2048
maxdir 256
tracks 1040
sectrk 16
blocksize 4096
maxdir 1024
skew 0 skew 0
boottrk 2
boottrk 18
os 2.2 os 2.2
end end
# RomWBW 360K floppy media
diskdef wbw_fd360
diskdef wbw_hd1_new
seclen 512 seclen 512
tracks 80
sectrk 9
blocksize 2048
maxdir 128
tracks 2064
sectrk 16
blocksize 4096
maxdir 1024
skew 0 skew 0
boottrk 4
boottrk 1042
os 2.2 os 2.2
end end
# RomWBW 1.20M floppy media
diskdef wbw_fd120
diskdef wbw_hd2_new
seclen 512 seclen 512
tracks 160
sectrk 15
blocksize 2048
maxdir 256
tracks 3112
sectrk 16
blocksize 4096
maxdir 1024
skew 0 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 os 2.2
end end

277
Source/CBIOS/cbios.asm

@ -252,9 +252,9 @@ DEVMAP:
; | | | ; | | |
; +--------------------+ +-> [DPH] +-> [DPH] ; +--------------------+ +-> [DPH] +-> [DPH]
; | ; |
; V-----+-------+-------+-------+--------+-----+-----+-----+
; DPH: | XLT | 0000H | 0000H | 0000H | DIRBUF | DPB | CSV | ALV |
; +---16+-----16+-----16+-----16+------16+-+-16+-+-16+-+-16+
; V-----+-------+-------+-------+--------+-----+-----+-----+--------+
; DPH: | XLT | 0000H | 0000H | 0000H | DIRBUF | DPB | CSV | ALV | LBAOFF |
; +---16+-----16+-----16+-----16+------16+-+-16+-+-16+-+-16+------32+
; (ONE DPH PER DRIVE) | | | ; (ONE DPH PER DRIVE) | | |
; | | +----------+ ; | | +----------+
; | | | ; | | |
@ -289,6 +289,7 @@ DPBMAP:
.DW DPB_FD360 ; MID_FD360 .DW DPB_FD360 ; MID_FD360
.DW DPB_FD120 ; MID_FD120 .DW DPB_FD120 ; MID_FD120
.DW DPB_FD111 ; MID_FD111 .DW DPB_FD111 ; MID_FD111
.DW DPB_HDNEW ; MID_HDNEW (1024 DIR ENTRIES)
; ;
DPBCNT .EQU ($ - DPBMAP) / 2 DPBCNT .EQU ($ - DPBMAP) / 2
; ;
@ -1199,6 +1200,7 @@ DSK_GETINF1: ; ERROR RETURN
DSK_SELECT: DSK_SELECT:
LD B,E ; SAVE E IN B FOR NOW LD B,E ; SAVE E IN B FOR NOW
CALL DSK_GETINF ; GET D=UNIT, E=SLICE, HL=DPH ADDRESS 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) RET NZ ; RETURN IF INVALID DRIVE (A=1, NZ SET, HL=0)
PUSH BC ; WE NEED B LATER, SAVE ON STACK PUSH BC ; WE NEED B LATER, SAVE ON STACK
; ;
@ -1209,13 +1211,15 @@ DSK_SELECT:
LD (SEKUNIT),A ; SAVE UNIT LD (SEKUNIT),A ; SAVE UNIT
LD (SEKDPH),HL ; SAVE DPH ADDRESS 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) ; RESTORE DE TO BC (FOR ACCESS TO DRIVE LOGIN BIT)
POP BC ; GET ORIGINAL E INTO B POP BC ; GET ORIGINAL E INTO B
@ -1234,11 +1238,24 @@ DSK_SELECT:
LD E,1 ; ENABLE MEDIA CHECK/DISCOVERY LD E,1 ; ENABLE MEDIA CHECK/DISCOVERY
RST 08 ; DO IT RST 08 ; DO IT
LD A,E ; RESULTANT MEDIA ID TO ACCUM LD A,E ; RESULTANT MEDIA ID TO ACCUM
LD (MEDID),A ; SAVE IT
OR A ; SET FLAGS OR A ; SET FLAGS
LD HL,0 ; ASSUME FAILURE LD HL,0 ; ASSUME FAILURE
RET Z ; BAIL OUT IF NO MEDIA 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 LD HL,DPBMAP ; HL = DPBMAP
RLCA ; DPBMAP ENTRIES ARE 2 BYTES EACH RLCA ; DPBMAP ENTRIES ARE 2 BYTES EACH
CALL ADDHLA ; ADD OFFSET TO HL CALL ADDHLA ; ADD OFFSET TO HL
@ -1249,12 +1266,22 @@ DSK_SELECT:
LD D,(HL) ; DE = ADDRESS OF DESIRED DPB LD D,(HL) ; DE = ADDRESS OF DESIRED DPB
; ;
; PLUG DPB INTO THE ACTIVE DPH ; 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 LD BC,10 ; OFFSET OF DPB IN DPH
ADD HL,BC ; HL := DPH.DPB ADD HL,BC ; HL := DPH.DPB
LD (HL),E ; SET LSB OF DPB IN DPH LD (HL),E ; SET LSB OF DPB IN DPH
INC HL ; BUMP TO MSB INC HL ; BUMP TO MSB
LD (HL),D ; SET MSB OF DPB IN DPH 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 #ENDIF
; ;
DSK_SELECT2: DSK_SELECT2:
@ -1262,6 +1289,131 @@ DSK_SELECT2:
XOR A ; FLAG SUCCESS XOR A ; FLAG SUCCESS
RET ; NORMAL RETURN 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: DSK_STATUS:
@ -1297,7 +1449,7 @@ DSK_WRITE:
; ;
; ;
#IFDEF PLTUNA #IFDEF PLTUNA
;
DSK_IO: DSK_IO:
PUSH BC PUSH BC
LD DE,(HSTTRK) ; GET TRACK INTO HL LD DE,(HSTTRK) ; GET TRACK INTO HL
@ -1338,15 +1490,10 @@ DSK_IO1:
RST 08 RST 08
OR A ; SET FLAGS BASED ON RESULT OR A ; SET FLAGS BASED ON RESULT
RET 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 A,(HSTUNIT) ; GET UNIT
LD C,A ; UNIT -> C LD C,A ; UNIT -> C
PUSH BC ; SAVE FUNC/UNIT PUSH BC ; SAVE FUNC/UNIT
@ -1356,7 +1503,7 @@ CHS:
LD A,D ; DEVICE TYPE -> A LD A,D ; DEVICE TYPE -> A
AND $F0 ; ISOLATE HIGH BITS AND $F0 ; ISOLATE HIGH BITS
CP DIODEV_FD ; FLOPPY? 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 ; FLOPPY SPECIFIC TRANSLATION ASSUMES FLOPPY IS DOUBLE-SIDED AND
; USES LOW ORDER BIT OF TRACK AS HEAD VALUE ; USES LOW ORDER BIT OF TRACK AS HEAD VALUE
@ -1368,40 +1515,37 @@ CHS:
SRL H ; SHIFT HEAD BIT OUT OF HL SRL H ; SHIFT HEAD BIT OUT OF HL
RR L ; ... AND INTO CARRY RR L ; ... AND INTO CARRY
RL D ; CARRY BIT (HEAD) INTO D 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 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 ; MAKE HBIOS CALL
; HBIOS FUNC SHOULD STILL BE IN B ; HBIOS FUNC SHOULD STILL BE IN B
; UNIT SHOULD STILL BE IN C ; UNIT SHOULD STILL BE IN C
; ;
DSK_IO2:
PUSH BC ; SAVE INCOMING FUNCTION, DEVICE/UNIT 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 RST 08 ; DO IT
@ -1411,10 +1555,11 @@ CHS2:
LD A,(BNKBIOS) ; GET BIOS BANK LD A,(BNKBIOS) ; GET BIOS BANK
LD D,A ; TRANSFER TO/FROM 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 RST 08 ; DO IT
OR A ; SET FLAGS OR A ; SET FLAGS
RET ; DONE RET ; DONE
;
#ENDIF #ENDIF
; ;
;================================================================================================== ;==================================================================================================
@ -1504,9 +1649,11 @@ STR_SEC .DB " SEC=$"
;STR_READONLY .DB "\r\nCBIOS Err: Read Only Drive$" ;STR_READONLY .DB "\r\nCBIOS Err: Read Only Drive$"
;STR_STALE .DB "\r\nCBIOS Err: Stale 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 DEFDRIVE .DB 0 ; DEFAULT DRIVE
CCPBUF .DW 0 ; ADDRESS OF CCP BUF IN BIOS BANK 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 #IFDEF PLTWBW
BNKBIOS .DB 0 ; BIOS BANK ID BNKBIOS .DB 0 ; BIOS BANK ID
@ -1536,6 +1683,7 @@ SEKUNIT .DB 0 ; DISK UNIT
SEKDPH .DW 0 ; ADDRESS OF ACTIVE (SELECTED) DPH SEKDPH .DW 0 ; ADDRESS OF ACTIVE (SELECTED) DPH
SEKOFF .DW 0 ; TRACK OFFSET IN EFFECT FOR SLICE SEKOFF .DW 0 ; TRACK OFFSET IN EFFECT FOR SLICE
SEKACT .DB TRUE ; ALWAYS TRUE! SEKACT .DB TRUE ; ALWAYS TRUE!
SEKLBA .FILL 4,0 ; LBA OFFSET
; ;
; RESULT OF CPM TO PHYSICAL TRANSLATION ; RESULT OF CPM TO PHYSICAL TRANSLATION
; ;
@ -1547,6 +1695,7 @@ XLTUNIT .DB 0
XLTDPH .DW 0 XLTDPH .DW 0
XLTOFF .DW 0 XLTOFF .DW 0
XLTACT .DB TRUE ; ALWAYS TRUE! XLTACT .DB TRUE ; ALWAYS TRUE!
XLTLBA .FILL 4,0 ; LBA OFFSET
; ;
XLTSIZ .EQU $ - XLT XLTSIZ .EQU $ - XLT
; ;
@ -1560,6 +1709,7 @@ HSTUNIT .DB 0 ; DISK UNIT IN BUFFER
HSTDPH .DW 0 ; CURRENT DPH ADDRESS HSTDPH .DW 0 ; CURRENT DPH ADDRESS
HSTOFF .DW 0 ; TRACK OFFSET IN EFFECT FOR SLICE HSTOFF .DW 0 ; TRACK OFFSET IN EFFECT FOR SLICE
HSTACT .DB 0 ; TRUE = BUFFER HAS VALID DATA HSTACT .DB 0 ; TRUE = BUFFER HAS VALID DATA
HSTLBA .FILL 4,0 ; LBA OFFSET
; ;
; SEQUENTIAL WRITE TRACKING FOR (UNA)LLOCATED BLOCK ; SEQUENTIAL WRITE TRACKING FOR (UNA)LLOCATED BLOCK
; ;
@ -1695,11 +1845,28 @@ DPB_HD:
.DB 31 ; BLM: BLOCK MASK .DB 31 ; BLM: BLOCK MASK
.DB 1 ; EXM: EXTENT MASK .DB 1 ; EXM: EXTENT MASK
.DW 2047 ; DSM: TOTAL STORAGE IN BLOCKS - 1 = (8MB / 4K BLS) - 1 = 2047 .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
.DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE
.DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE
.DW 0 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 .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 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 ; IBM 720KB 3.5" FLOPPY DRIVE, 80 TRKS, 36 SECS/TRK, 512 BYTES/SEC
@ -2650,7 +2817,8 @@ DPH_INIT:
LD H,0 ; ... INTO HL LD H,0 ; ... INTO HL
ADD HL,HL ; MULTIPLY ADD HL,HL ; MULTIPLY
ADD HL,HL ; ... BY SIZE 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 ADD HL,HL ; ... FOR TOTAL SIZE
CALL ALLOC ; ALLOCATE THE SPACE CALL ALLOC ; ALLOCATE THE SPACE
CALL C,PANIC ; SHOULD NEVER ERROR CALL C,PANIC ; SHOULD NEVER ERROR
@ -2707,7 +2875,8 @@ DPH_INIT2:
LD (HL),D ; ... DRIVE MAP LD (HL),D ; ... DRIVE MAP
INC HL ; AND BUMP TO START OF NEXT ENTRY INC HL ; AND BUMP TO START OF NEXT ENTRY
; UPDATE DPH ALLOCATION TOP ; 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 EX DE,HL ; HL := DPH POINTER
CALL ADDHLA ; CALC NEW DPHTOP CALL ADDHLA ; CALC NEW DPHTOP
LD (DPHTOP),HL ; SAVE IT LD (DPHTOP),HL ; SAVE IT

12
Source/CBIOS/util.asm

@ -430,3 +430,15 @@ PRTHEXBUF1:
INC DE INC DE
DJNZ PRTHEXBUF1 DJNZ PRTHEXBUF1
RET 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

442
Source/CPM3/biosldr.z80

@ -51,57 +51,67 @@
jp 0 ; reserved for future expansion jp 0 ; reserved for future expansion
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 (stksav),sp
ld sp,stack ld sp,stack
boot1:
ld de,msgunit
call writestr
call cin
push af
call cout
pop af
; Do the real work
call boot0
; Restore original stack and return
ld sp,(stksav)
ret
sub '0'
ld (unit),a
jr c,selerr
boot0:
if cmdline
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 ld bc,0F810h ; HBIOS, get disk unit count
call 0FFF0h ; do it, E := disk unit count call 0FFF0h ; do it, E := disk unit count
ld a,(unit) ; get unit num back ld a,(unit) ; get unit num back
cp e ; compare to entry cp e ; compare to entry
jr nc,selerr ; loop if too high jr nc,selerr ; loop if too high
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
jr boot2
; 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: 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: boot2:
ld de,crlf
call writestr
ld sp,(stksav)
; Record unit & slice w/ HBIOS
ld bc,0F9E0h ; HBIOS func: set boot info ld bc,0F9E0h ; HBIOS func: set boot info
ld a,(unit) ; get unit ld a,(unit) ; get unit
ld d,a ; put in D ld d,a ; put in D
@ -112,6 +122,7 @@ boot2:
else else
; Get unit & slice from HBIOS
ld bc,0F8E0h ; HBIOS func: get boot info ld bc,0F8E0h ; HBIOS func: get boot info
call 0FFF0h ; do it, D := boot unit, E: := slice call 0FFF0h ; do it, D := boot unit, E: := slice
ld a,d ; move unit to A ld a,d ; move unit to A
@ -121,27 +132,118 @@ boot2:
endif endif
; 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 a,(unit) ; Get boot unit
ld c,a ; put in C ld c,a ; put in C
ld b,18h ; HBIOS Media function ld b,18h ; HBIOS Media function
ld e,1 ; Enable media check/discovery ld e,1 ; Enable media check/discovery
call 0FFF0H ; HBIOS call 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
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 hl,dpb$start - dpb$sz
ld de,dpb$sz ld de,dpb$sz
ld b,a ; loop count
dsk$login1:
ld a,(medid) ; get media id
ld b,a ; to loop count
boot10:
add hl,de ; next dpb add hl,de ; next dpb
djnz dsk$login1 ; loop as needed
djnz boot10 ; loop as needed
; hl is ptr to desired dpb
; Stuff DPB ptr (HL) into DPH
ld de,dph0 ; load DPH pointer ld de,dph0 ; load DPH pointer
ex de,hl ; de = DPB adr, hl = DPH adr ex de,hl ; de = DPB adr, hl = DPH adr
push de ; save DPB adr push de ; save DPB adr
@ -149,10 +251,10 @@ dsk$login1:
add hl,de ; hl = adr of DPB field in DPH add hl,de ; hl = adr of DPB field in DPH
pop de ; recover DPB adr pop de ; recover DPB adr
ld (hl),e ; update LSB ld (hl),e ; update LSB
inc hl
ld (hl),d ; udpate MSB
inc hl ; point to MSB
ld (hl),d ; update MSB
ret
ret ; done
wboot: wboot:
ld a,81H ld a,81H
@ -162,15 +264,14 @@ const:
ld a,82H ld a,82H
halt halt
conin: 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: conout:
ld e,c ; output character in E 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 bc,0180h ; unit 80h (console), func 1 = COUT
jp 0FFF0h
list: list:
ld a,85H ld a,85H
halt halt
@ -197,61 +298,100 @@ setsec:
setdma: setdma:
ld (dma),bc ld (dma),bc
ret ret
read: read:
; Check device type
ld a,(unit) ; get unit ld a,(unit) ; get unit
ld c,a ; BIOS Disk Unit in C 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 ld b,17h ; HBIOS DEVICE function
rst 08 ; Do it, D=device type rst 08 ; Do it, D=device type
ld a,d ; put in accum ld a,d ; put in accum
and 0F0h ; isolate high bits 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? 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
jr nz,read2 ; 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 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 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
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 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
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
ret
write: write:
ld a,8EH ld a,8EH
halt halt
@ -291,10 +431,11 @@ flush:
halt halt
move: 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: time:
ld a,9AH ld a,9AH
halt halt
@ -309,20 +450,19 @@ xmove:
halt halt
cin: 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: 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: writestr:
push af push af
@ -339,12 +479,8 @@ writestr2:
pop af pop af
ret ret
;
; multiply 8-bit values
; in: multiply h by e
; out: hl = result, e = 0, b = 0
;
mult8: mult8:
; Multiply: H := H * E
ld d,0 ld d,0
ld l,d ld l,d
ld b,8 ld b,8
@ -356,6 +492,46 @@ mult8_noadd:
djnz mult8_loop djnz mult8_loop
ret 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: $' msgunit db 13,10,13,10,'Boot CP/M 3 from Disk Unit: $'
msgslc db ' Slice: $' msgslc db ' Slice: $'
msginv db 13,10,13,10,'*** Invalid Selection ***$' msginv db 13,10,13,10,'*** Invalid Selection ***$'
@ -411,7 +587,7 @@ dpb$hd: ; 8MB Hard Disk Drive
db 31 ; blm: block mask db 31 ; blm: block mask
db 1 ; exm: extent mask db 1 ; exm: extent mask
dw 2047 ; dsm: total storage in blocks - 1 = (8mb / 4k bls) - 1 = 2047 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 11110000b ; al0: dir blk bit map, first byte
db 00000000b ; al1: dir blk bit map, second byte db 00000000b ; al1: dir blk bit map, second byte
dw 8000h ; cks: directory check vector size - permanent storage = 8000H dw 8000h ; cks: directory check vector size - permanent storage = 8000H
@ -489,6 +665,20 @@ dpb_fd111: ; 8" DS/DD Floppy Drive (1.11M)
db 2 ; psh: 2 for 512 byte sectors db 2 ; psh: 2 for 512 byte sectors
db 3 ; phm: (512 / 128) - 1 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
dph0: dw 0 ; xlt, 0 means no translation dph0: dw 0 ; xlt, 0 means no translation
db 0,0,0,0,0,0,0,0,0 ; scratch (9 bytes) db 0,0,0,0,0,0,0,0,0 ; scratch (9 bytes)
db 0 ; mf: media flag db 0 ; mf: media flag
@ -524,6 +714,10 @@ trk ds 2 ; current track
sect ds 2 ; current sector sect ds 2 ; current sector
dma ds 2 ; current DMA address 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) csvbuf ds 128 ; length (CSV) = ((DRM+1)/4)
alvbuf ds 512 ; length (ALV) = ((DSM+1)/4) alvbuf ds 512 ; length (ALV) = ((DSM+1)/4)
dirbuf ds 512 ; sector buffer dirbuf ds 512 ; sector buffer
@ -531,6 +725,6 @@ dtabuf ds 512 ; sector buffer
ds 64 ds 64
stack equ $ stack equ $
stksav dw 0
stksav ds 2
end end

2
Source/CPM3/boot.z80

@ -41,7 +41,7 @@ tpa$bank equ 0
if banked if banked
; Clone page zero from bank 0 to additional banks ; Clone page zero from bank 0 to additional banks
ld b,3 ; last bank
ld b,4 ; last bank
ld c,0 ; src bank ld c,0 ; src bank
init$2: init$2:
push bc ; save bank id's push bc ; save bank id's

482
Source/CPM3/diskio.z80

@ -37,7 +37,7 @@
extrn ?bnkxlt extrn ?bnkxlt
;extrn phex8, cout
extrn phex8, cout
; CP/M 3 Disk definition macros ; CP/M 3 Disk definition macros
@ -62,6 +62,7 @@ bell equ 7
dw dsk$init dw dsk$init
db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot)
dph0: dph 0,dpb$max ; Real DPB filled in at disk login dph0: dph 0,dpb$max ; Real DPB filled in at disk login
dw 0, 0 ; LBA Offset
dw dsk$write dw dsk$write
dw dsk$read dw dsk$read
@ -69,6 +70,7 @@ dph0: dph 0,dpb$max ; Real DPB filled in at disk login
dw dsk$init dw dsk$init
db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot)
dph1: dph 0,dpb$max ; Real DPB filled in at disk login dph1: dph 0,dpb$max ; Real DPB filled in at disk login
dw 0, 0 ; LBA Offset
dw dsk$write dw dsk$write
dw dsk$read dw dsk$read
@ -76,6 +78,7 @@ dph1: dph 0,dpb$max ; Real DPB filled in at disk login
dw dsk$init dw dsk$init
db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot)
dph2: dph 0,dpb$max ; Real DPB filled in at disk login dph2: dph 0,dpb$max ; Real DPB filled in at disk login
dw 0, 0 ; LBA Offset
dw dsk$write dw dsk$write
dw dsk$read dw dsk$read
@ -83,6 +86,7 @@ dph2: dph 0,dpb$max ; Real DPB filled in at disk login
dw dsk$init dw dsk$init
db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot)
dph3: dph 0,dpb$max ; Real DPB filled in at disk login dph3: dph 0,dpb$max ; Real DPB filled in at disk login
dw 0, 0 ; LBA Offset
dw dsk$write dw dsk$write
dw dsk$read dw dsk$read
@ -90,6 +94,7 @@ dph3: dph 0,dpb$max ; Real DPB filled in at disk login
dw dsk$init dw dsk$init
db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot)
dph4: dph 0,dpb$max ; Real DPB filled in at disk login dph4: dph 0,dpb$max ; Real DPB filled in at disk login
dw 0, 0 ; LBA Offset
dw dsk$write dw dsk$write
dw dsk$read dw dsk$read
@ -97,6 +102,7 @@ dph4: dph 0,dpb$max ; Real DPB filled in at disk login
dw dsk$init dw dsk$init
db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot)
dph5: dph 0,dpb$max ; Real DPB filled in at disk login dph5: dph 0,dpb$max ; Real DPB filled in at disk login
dw 0, 0 ; LBA Offset
dw dsk$write dw dsk$write
dw dsk$read dw dsk$read
@ -104,6 +110,7 @@ dph5: dph 0,dpb$max ; Real DPB filled in at disk login
dw dsk$init dw dsk$init
db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot)
dph6: dph 0,dpb$max ; Real DPB filled in at disk login dph6: dph 0,dpb$max ; Real DPB filled in at disk login
dw 0, 0 ; LBA Offset
dw dsk$write dw dsk$write
dw dsk$read dw dsk$read
@ -111,6 +118,7 @@ dph6: dph 0,dpb$max ; Real DPB filled in at disk login
dw dsk$init dw dsk$init
db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot)
dph7: dph 0,dpb$max ; Real DPB filled in at disk login dph7: dph 0,dpb$max ; Real DPB filled in at disk login
dw 0, 0 ; LBA Offset
dw dsk$write dw dsk$write
dw dsk$read dw dsk$read
@ -118,6 +126,7 @@ dph7: dph 0,dpb$max ; Real DPB filled in at disk login
dw dsk$init dw dsk$init
db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot)
dph8: dph 0,dpb$max ; Real DPB filled in at disk login dph8: dph 0,dpb$max ; Real DPB filled in at disk login
dw 0, 0 ; LBA Offset
dw dsk$write dw dsk$write
dw dsk$read dw dsk$read
@ -125,6 +134,7 @@ dph8: dph 0,dpb$max ; Real DPB filled in at disk login
dw dsk$init dw dsk$init
db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot)
dph9: dph 0,dpb$max ; Real DPB filled in at disk login dph9: dph 0,dpb$max ; Real DPB filled in at disk login
dw 0, 0 ; LBA Offset
dw dsk$write dw dsk$write
dw dsk$read dw dsk$read
@ -132,6 +142,7 @@ dph9: dph 0,dpb$max ; Real DPB filled in at disk login
dw dsk$init dw dsk$init
db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot)
dph10: dph 0,dpb$max ; Real DPB filled in at disk login dph10: dph 0,dpb$max ; Real DPB filled in at disk login
dw 0, 0 ; LBA Offset
dw dsk$write dw dsk$write
dw dsk$read dw dsk$read
@ -139,6 +150,7 @@ dph10: dph 0,dpb$max ; Real DPB filled in at disk login
dw dsk$init dw dsk$init
db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot)
dph11: dph 0,dpb$max ; Real DPB filled in at disk login dph11: dph 0,dpb$max ; Real DPB filled in at disk login
dw 0, 0 ; LBA Offset
dw dsk$write dw dsk$write
dw dsk$read dw dsk$read
@ -146,6 +158,7 @@ dph11: dph 0,dpb$max ; Real DPB filled in at disk login
dw dsk$init dw dsk$init
db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot)
dph12: dph 0,dpb$max ; Real DPB filled in at disk login dph12: dph 0,dpb$max ; Real DPB filled in at disk login
dw 0, 0 ; LBA Offset
dw dsk$write dw dsk$write
dw dsk$read dw dsk$read
@ -153,6 +166,7 @@ dph12: dph 0,dpb$max ; Real DPB filled in at disk login
dw dsk$init dw dsk$init
db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot)
dph13: dph 0,dpb$max ; Real DPB filled in at disk login dph13: dph 0,dpb$max ; Real DPB filled in at disk login
dw 0, 0 ; LBA Offset
dw dsk$write dw dsk$write
dw dsk$read dw dsk$read
@ -160,6 +174,7 @@ dph13: dph 0,dpb$max ; Real DPB filled in at disk login
dw dsk$init dw dsk$init
db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot)
dph14: dph 0,dpb$max ; Real DPB filled in at disk login dph14: dph 0,dpb$max ; Real DPB filled in at disk login
dw 0, 0 ; LBA Offset
dw dsk$write dw dsk$write
dw dsk$read dw dsk$read
@ -167,6 +182,7 @@ dph14: dph 0,dpb$max ; Real DPB filled in at disk login
dw dsk$init dw dsk$init
db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot) db 0,0 ; HBIOS Disk Unit/Slice (filled in at boot)
dph15: dph 0,dpb$max ; Real DPB filled in at disk login dph15: dph 0,dpb$max ; Real DPB filled in at disk login
dw 0, 0 ; LBA Offset
cseg ; DPB must be resident cseg ; DPB must be resident
@ -176,8 +192,8 @@ dpb$max:
db 31 ; blm: block mask db 31 ; blm: block mask
db 1 ; exm: extent mask db 1 ; exm: extent mask
dw 2047 ; dsm: total storage in blocks - 1 = (8mb / 4k bls) - 1 = 2047 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 db 00000000b ; al1: dir blk bit map, second byte
dw 64 ; cks: directory check vector size - 256 / 4 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 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 2 ; psh: 2 for 512 byte sectors
db 3 ; phm: (512 / 128) - 1 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 dw 64 ; spt: sectors per track
db 5 ; bsh: block shift factor db 5 ; bsh: block shift factor
db 31 ; blm: block mask db 31 ; blm: block mask
db 1 ; exm: extent mask db 1 ; exm: extent mask
dw 2047 ; dsm: total storage in blocks - 1 = (8mb / 4k bls) - 1 = 2047 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 11110000b ; al0: dir blk bit map, first byte
db 00000000b ; al1: dir blk bit map, second byte db 00000000b ; al1: dir blk bit map, second byte
dw 8000h ; cks: directory check vector size - permanent storage = 8000H 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 2 ; psh: 2 for 512 byte sectors
db 3 ; phm: (512 / 128) - 1 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 dseg ; rest is banked
@ -371,48 +401,152 @@ dsk$login:
;ld a,'L' ;ld a,'L'
;call cout ;call cout
push de ; save DPH ptr
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
; check media
ld a,(@rdrv) ; get disk unit
;halt
media:
; Set retry address
ld hl,media
ld (retry$adr),hl
; Sense media to determine media format
ld a,(unit) ; Get disk unit
ld c,a ; put in C ld c,a ; put in C
ld b,18h ; HBIOS Media function ld b,18h ; HBIOS Media function
ld e,1 ; Enable media check/discovery ld e,1 ; Enable media check/discovery
;rst 08
call 0FFF0H ; HBIOS call 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
dsk$login0:
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
media9:
; Locate DPB corresponding to media id
ld hl,dpb$start - dpb$sz ld hl,dpb$start - dpb$sz
ld de,dpb$sz ld de,dpb$sz
ld b,a ; loop count
dsk$login1:
ld a,(medid) ; get media id
ld b,a ; to loop count
media10:
add hl,de ; next dpb add hl,de ; next dpb
djnz dsk$login1 ; loop as needed
djnz media10 ; loop as needed
; hl is ptr to desired dpb
pop de ; restore DPH ptr
;halt
; 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 ex de,hl ; de = DPB adr, hl = DPH adr
push de ; save DPB adr push de ; save DPB adr
ld de,12 ; offset of DPB in DPH ld de,12 ; offset of DPB in DPH
add hl,de ; hl = adr of DPB field in DPH add hl,de ; hl = adr of DPB field in DPH
pop de ; recover DPB adr pop de ; recover DPB adr
ld (hl),e ; update LSB ld (hl),e ; update LSB
inc hl
ld (hl),d ; udpate MSB
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 ret ; done
; disk READ and WRITE entry points. ; disk READ and WRITE entry points.
; these entries are called with the following arguments: ; these entries are called with the following arguments:
@ -429,116 +563,119 @@ dsk$login1:
; if necessary, then return an error code in <A> ; if necessary, then return an error code in <A>
dsk$read: 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
dsk$write:
ld a,14h ; HBIOS disk write function
ld (func),a ; save it
jr dsk$rw ; common disk read/write code
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
dsk$rw:
; Common disk read/write routine
; Assumes func is set to HBIOS read or write
;call phex8
ret ; return
; Save XDPH address
ld (curdph),de ; save to curdph
; lxi h,read$msg ; point at " Read "
; mvi a,88h ! mvi b,01h ; 1797 read + Z80DMA direction
; jmp rw$common
; Set retry address
ld hl,dsk$rw
ld (retry$adr),hl
dsk$write:
;ld ix,32H
;halt
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
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
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
; Check device type
ld a,(@rdrv) ; get unit
ld c,a ; BIOS Disk Unit in C 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 ld b,17h ; HBIOS DEVICE function
rst 08 ; Do it, D=device type
call 0FFF0h ; do it, D=device type
ld a,d ; put in accum ld a,d ; put in accum
and 0F0h ; isolate high bits 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? 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
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
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 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
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 ; xlat to HBIOS
else
ld a,(0FFE0H) ; get current bank
endif
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 ; multiply 8-bit values
@ -557,6 +694,93 @@ mult8_noadd:
djnz mult8_loop djnz mult8_loop
ret 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), ;rw$common: ; seek to correct track (if necessary),
; ; initialize DMA controller, ; ; initialize DMA controller,
; ; and issue 1797 command. ; ; and issue 1797 command.

4
Source/CPM3/genbnk.dat

@ -8,12 +8,12 @@ MEMTOP = FD
BNKSWT = Y BNKSWT = Y
COMBAS = 80 COMBAS = 80
LERROR = Y LERROR = Y
NUMSEGS = 03
NUMSEGS = 04
MEMSEG00 = 01,43,00 MEMSEG00 = 01,43,00
MEMSEG01 = 0E,72,02 MEMSEG01 = 0E,72,02
MEMSEG02 = 01,7F,03 MEMSEG02 = 01,7F,03
MEMSEG03 = 01,7F,04 MEMSEG03 = 01,7F,04
MEMSEG04 = 00,C0,05
MEMSEG04 = 01,7F,05
MEMSEG05 = 00,C0,06 MEMSEG05 = 00,C0,06
MEMSEG06 = 00,C0,07 MEMSEG06 = 00,C0,07
MEMSEG07 = 00,C0,08 MEMSEG07 = 00,C0,08

3
Source/CPM3/move.z80

@ -69,7 +69,8 @@ xbnkmov:
; 1: TPA BID_AUX 8Ch ; 1: TPA BID_AUX 8Ch
; 2: BUFS BID_AUX-1 8Bh ; 2: BUFS BID_AUX-1 8Bh
; 3: BUFS BID_AUX-2 8Ah ; 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 ; N.B., Below BID_AUX is considered RAM disk bank. Need to
; make sure RAM disk is kept small enough to stay below ; make sure RAM disk is kept small enough to stay below

3
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 true equ -1
false equ not true false equ not true

2
Source/CPM3/util.z80

@ -51,7 +51,7 @@ bin2bcd1:
pop bc pop bc
ret ret
if 0
if 1
; ;
; Print the hex word value in HL ; Print the hex word value in HL
; ;

139
Source/HBIOS/diskdefs

@ -297,121 +297,158 @@ diskdef wbw_rom1024
os 2.2 os 2.2
end 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 seclen 512
tracks 12
sectrk 64
tracks 160
sectrk 18
blocksize 2048 blocksize 2048
maxdir 256 maxdir 256
skew 0 skew 0
boottrk 0
boottrk 2
os 2.2 os 2.2
end 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 seclen 512
tracks 28
sectrk 64
tracks 160
sectrk 15
blocksize 2048 blocksize 2048
maxdir 256 maxdir 256
skew 0 skew 0
boottrk 0
boottrk 2
os 2.2 os 2.2
end 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 diskdef wbw_hd0
seclen 512 seclen 512
tracks 65
sectrk 256
tracks 1040
sectrk 16
blocksize 4096 blocksize 4096
maxdir 512 maxdir 512
skew 0 skew 0
boottrk 1
boottrk 16
os 2.2 os 2.2
end end
diskdef wbw_hd1 diskdef wbw_hd1
seclen 512 seclen 512
tracks 130
sectrk 256
tracks 2080
sectrk 16
blocksize 4096 blocksize 4096
maxdir 512 maxdir 512
skew 0 skew 0
boottrk 66
boottrk 1056
os 2.2 os 2.2
end end
diskdef wbw_hd2 diskdef wbw_hd2
seclen 512 seclen 512
tracks 195
sectrk 256
tracks 3120
sectrk 16
blocksize 4096 blocksize 4096
maxdir 512 maxdir 512
skew 0 skew 0
boottrk 131
boottrk 2096
os 2.2 os 2.2
end end
diskdef wbw_hd3 diskdef wbw_hd3
seclen 512 seclen 512
tracks 260
sectrk 256
tracks 4160
sectrk 16
blocksize 4096 blocksize 4096
maxdir 512 maxdir 512
skew 0 skew 0
boottrk 196
boottrk 3136
os 2.2 os 2.2
end 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 seclen 512
tracks 160
sectrk 9
blocksize 2048
maxdir 128
tracks 1024
sectrk 16
blocksize 4096
maxdir 1024
skew 0 skew 0
boottrk 4
boottrk 2
os 2.2 os 2.2
end 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 seclen 512
tracks 160
sectrk 18
blocksize 2048
maxdir 256
tracks 1040
sectrk 16
blocksize 4096
maxdir 1024
skew 0 skew 0
boottrk 2
boottrk 18
os 2.2 os 2.2
end end
# RomWBW 360K floppy media
diskdef wbw_fd360
diskdef wbw_hd1_new
seclen 512 seclen 512
tracks 80
sectrk 9
blocksize 2048
maxdir 128
tracks 2064
sectrk 16
blocksize 4096
maxdir 1024
skew 0 skew 0
boottrk 4
boottrk 1042
os 2.2 os 2.2
end end
# RomWBW 1.20M floppy media
diskdef wbw_fd120
diskdef wbw_hd2_new
seclen 512 seclen 512
tracks 160
sectrk 15
blocksize 2048
maxdir 256
tracks 3112
sectrk 16
blocksize 4096
maxdir 1024
skew 0 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 os 2.2
end end

548
Source/HBIOS/romldr.asm

@ -106,7 +106,7 @@ bid_cur .equ -1 ; used below to indicate current bank
; ;
start: start:
ld sp,bl_stack ; setup private stack 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 ; 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. ; 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 ld hl,str_newcon ; new console msg
call pstr ; print string on cur console call pstr ; print string on cur console
pop af ; restore new console unit pop af ; restore new console unit
call PRTDECB ; print unit num
call prtdecb ; print unit num
; ;
; Set console unit ; Set console unit
ld b,BF_SYSPOKE ; HBIOS func: POKE ld b,BF_SYSPOKE ; HBIOS func: POKE
@ -479,7 +479,7 @@ setcon:
reboot: reboot:
ld hl,str_reboot ; point to message ld hl,str_reboot ; point to message
call pstr ; print it call pstr ; print it
call LDELAY ; wait for message to display
call ldelay ; wait for message to display
; ;
#if (BIOS == BIOS_WBW) #if (BIOS == BIOS_WBW)
; ;
@ -618,11 +618,11 @@ diskboot:
ld hl,str_boot1 ld hl,str_boot1
call pstr call pstr
ld a,(bootunit) ld a,(bootunit)
call PRTDECB
call prtdecb
ld hl,str_boot2 ld hl,str_boot2
call pstr call pstr
ld a,(bootslice) ld a,(bootslice)
call PRTDECB
call prtdecb
; ;
#if (DSKYENABLE) #if (DSKYENABLE)
ld hl,msg_load ; point to load message ld hl,msg_load ; point to load message
@ -632,13 +632,21 @@ diskboot:
#if (BIOS == BIOS_WBW) #if (BIOS == BIOS_WBW)
; ;
; Check that drive actually exists ; 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 b,BF_SYSGET ; HBIOS func: sys get
ld c,BF_SYSGET_DIOCNT ; HBIOS sub-func: disk count ld c,BF_SYSGET_DIOCNT ; HBIOS sub-func: disk count
rst 08 ; do it, E=disk count rst 08 ; do it, E=disk count
ld a,(bootunit) ; get boot disk unit ld a,(bootunit) ; get boot disk unit
cp e ; compare to count cp e ; compare to count
jp nc,err_nodisk ; handle no disk err 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 ; If non-zero slice requested, confirm device can handle it
ld a,(bootslice) ; get slice ld a,(bootslice) ; get slice
@ -652,40 +660,6 @@ diskboot:
cp DIODEV_IDE ; IDE is max slice device type cp DIODEV_IDE ; IDE is max slice device type
jp c,err_noslice ; no such slice, handle err 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 #endif
; ;
#if (BIOS == BIOS_UNA) #if (BIOS == BIOS_UNA)
@ -712,12 +686,67 @@ diskboot1:
jr z,diskboot1 ; if so, OK jr z,diskboot1 ; if so, OK
jp err_noslice ; no such slice, handle err jp err_noslice ; no such slice, handle err
; ;
#endif
;
diskboot1: 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 ; Add slice offset
ld a,(bootslice) ; get boot slice, A is loop cnt 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: diskboot2:
or a ; set flags to check loop ctr or a ; set flags to check loop ctr
jr z,diskboot4 ; done if counter exhausted jr z,diskboot4 ; done if counter exhausted
@ -729,30 +758,30 @@ diskboot3:
jr diskboot2 ; and loop jr diskboot2 ; and loop
; ;
diskboot4: 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 ld bc,2 ; sector offset
add hl,bc ; add to LBA value low word add hl,bc ; add to LBA value low word
jr nc,diskboot5 ; check for carry jr nc,diskboot5 ; check for carry
inc de ; if so, bump high word inc de ; if so, bump high word
diskboot5: 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 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 ; Check signature
ld de,(bb_sig) ; get signature read ld de,(bb_sig) ; get signature read
@ -762,6 +791,7 @@ diskboot5:
ld a,$5A ; expected value of second byte ld a,$5A ; expected value of second byte
cp e ; compare cp e ; compare
jp nz,err_sig ; handle error jp nz,err_sig ; handle error
call pdot ; show progress
; ;
; Print disk boot info ; Print disk boot info
; Volume "xxxxxxx" (0xXXXX-0xXXXX, entry @ 0xXXXX) ; Volume "xxxxxxx" (0xXXXX-0xXXXX, entry @ 0xXXXX)
@ -774,17 +804,17 @@ diskboot5:
call pstr ; print call pstr ; print
push hl ; save string ptr push hl ; save string ptr
ld bc,(bb_cpmloc) ; get load loc ld bc,(bb_cpmloc) ; get load loc
call PRTHEXWORD ; print it
call prthexword ; print it
pop hl ; restore string ptr pop hl ; restore string ptr
call pstr ; print call pstr ; print
push hl ; save string ptr push hl ; save string ptr
ld bc,(bb_cpmend) ; get load end ld bc,(bb_cpmend) ; get load end
call PRTHEXWORD ; print it
call prthexword ; print it
pop hl ; restore string ptr pop hl ; restore string ptr
call pstr ; print call pstr ; print
push hl ; save string ptr push hl ; save string ptr
ld bc,(bb_cpment) ; get load end ld bc,(bb_cpment) ; get load end
call PRTHEXWORD ; print it
call prthexword ; print it
pop hl ; restore string ptr pop hl ; restore string ptr
call pstr ; print call pstr ; print
; ;
@ -798,19 +828,25 @@ diskboot5:
ld (loadcnt),a ; ... and save it ld (loadcnt),a ; ... and save it
call pdot ; show progress 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 a,(bootunit) ; get boot disk unit
ld c,a ; put in C 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 call pdot ; show progress
;
#if (BIOS == BIOS_WBW)
; ;
; Record boot unit/slice ; Record boot unit/slice
ld b,BF_SYSSET ; hb func: set hbios parameter ld b,BF_SYSSET ; hb func: set hbios parameter
@ -823,36 +859,10 @@ diskboot5:
ld e,a ; save in E ld e,a ; save in E
rst 08 rst 08
jp nz,err_api ; handle errors jp nz,err_api ; handle errors
call pdot ; show progress
; ;
#endif #endif
; ;
#if (BIOS == BIOS_UNA) #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 ; Record boot unit/slice
; UNA provides only a single byte to record the boot unit ; UNA provides only a single byte to record the boot unit
@ -876,6 +886,8 @@ diskboot6:
call pdot ; show progress call pdot ; show progress
; ;
#endif #endif
;
call pdot ; show progress
; ;
#if (DSKYENABLE) #if (DSKYENABLE)
ld hl,msg_go ; point to go message ld hl,msg_go ; point to go message
@ -886,6 +898,55 @@ diskboot6:
ld hl,(bb_cpment) ; get entry vector ld hl,(bb_cpment) ; get entry vector
jp (hl) ; and go there 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 ; Utility functions
;======================================================================= ;=======================================================================
@ -1079,6 +1140,269 @@ isnum1:
or $FF ; set NZ or $FF ; set NZ
ret ; and done 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) ; Console character I/O helper routines (registers preserved)
;======================================================================= ;=======================================================================
@ -1241,7 +1565,7 @@ prtall1:
ld hl,str_disk ; prefix string ld hl,str_disk ; prefix string
call pstr ; display it call pstr ; display it
ld a,c ; index ld a,c ; index
call PRTDECB ; print it
call prtdecb ; print it
ld hl,str_on ; separator string ld hl,str_on ; separator string
call pstr call pstr
push bc ; save loop control push bc ; save loop control
@ -1268,7 +1592,7 @@ prtdrv:
and $0F ; isolate device bits and $0F ; isolate device bits
add a,a ; multiple by two for word table add a,a ; multiple by two for word table
ld hl,devtbl ; point to start of 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 ld a,(hl) ; deref HL for string adr
inc hl ; ... inc hl ; ...
ld h,(hl) ; ... ld h,(hl) ; ...
@ -1277,7 +1601,7 @@ prtdrv:
pop hl ; recover HL pop hl ; recover HL
pop de ; recover DE pop de ; recover DE
ld a,e ; device number ld a,e ; device number
call PRTDECB ; print it
call prtdecb ; print it
ld a,':' ; suffix ld a,':' ; suffix
call cout ; print it call cout ; print it
ret ret
@ -1340,7 +1664,7 @@ prtdrv:
ld hl,str_disk ; prefix string ld hl,str_disk ; prefix string
call pstr ; display it call pstr ; display it
ld a,b ; index ld a,b ; index
call PRTDECB ; print it
call prtdecb ; print it
ld a,' ' ; formatting ld a,' ' ; formatting
call cout ; do it call cout ; do it
ld a,'=' ; formatting ld a,'=' ; formatting
@ -1380,7 +1704,7 @@ prtdrv2: ; print device
pop bc ; recover unit pop bc ; recover unit
call pstr ; print device name call pstr ; print device name
ld a,b ; unit to a ld a,b ; unit to a
call PRTDECB ; print it
call prtdecb ; print it
ld a,':' ; device name suffix ld a,':' ; device name suffix
call cout ; print it call cout ; print it
ret ; done ret ; done
@ -1452,10 +1776,12 @@ str_err_api .db "Unexpected hardware BIOS API failure",0
;======================================================================= ;=======================================================================
; ;
#define USEDELAY #define USEDELAY
#include "util.asm"
; #include "util.asm"
; ;
#if (DSKYENABLE) #if (DSKYENABLE)
#define DSKY_KBD #define DSKY_KBD
VDELAY .equ vdelay
DLY2 .equ dly2
#include "dsky.asm" #include "dsky.asm"
#endif #endif
; ;
@ -1492,6 +1818,7 @@ str_binfo2 .db $22," [0x",0
str_binfo3 .db "-0x",0 str_binfo3 .db "-0x",0
str_binfo4 .db ", entry @ 0x",0 str_binfo4 .db ", entry @ 0x",0
str_binfo5 .db "]",0 str_binfo5 .db "]",0
str_ldsec .db ", Sector 0x",0
; ;
str_help .db "\r\n" str_help .db "\r\n"
.db "\r\n L - List ROM Applications" .db "\r\n L - List ROM Applications"
@ -1651,9 +1978,12 @@ bid_ldr .ds 1 ; bank at startup
#endif #endif
#if (BIOS == BIOS_UNA) #if (BIOS == BIOS_UNA)
bid_ldr .ds 2 ; bank at startup bid_ldr .ds 2 ; bank at startup
loadlba .ds 4 ; lba for load, dword
#endif #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 ra_tbl_loc .ds 2 ; points to active ra_tbl
bootunit .ds 1 ; boot disk unit bootunit .ds 1 ; boot disk unit
bootslice .ds 1 ; boot disk slice 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_cpmloc .ds 2 ; final ram dest for cpm/cbios
bb_cpmend .ds 2 ; end address for load bb_cpmend .ds 2 ; end address for load
bb_cpment .ds 2 ; CP/M entry point (cbios boot) 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 .end

26
Source/Images/Build.cmd

@ -4,24 +4,24 @@ setlocal
echo. echo.
echo Building Floppy Disk Images... echo Building Floppy Disk Images...
echo. 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.
echo Building Hard Disk Images... echo Building Hard Disk Images...
echo. 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.
echo Building Combo Disk Image... echo Building Combo Disk Image...

38
Source/Images/BuildFD.ps1

@ -1,10 +1,9 @@
#Param([Parameter(Mandatory)]$Disk, $SysFile="")
Param($Disk, $SysFile="")
Param($Disk, $Format="wbw_fd144", $SysFile="")
$ErrorAction = 'Stop' $ErrorAction = 'Stop'
$ImgFile = "fd_${Disk}.img" $ImgFile = "fd_${Disk}.img"
$Fmt = "wbw_fd144"
$MediaID = 6
$Size = 1440KB $Size = 1440KB
$CpmToolsPath = '../../Tools/cpmtools' $CpmToolsPath = '../../Tools/cpmtools'
@ -13,35 +12,31 @@ $env:PATH = $CpmToolsPath + ';' + $env:PATH
if (-not (Test-Path("d_${Disk}/"))) 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 return
} }
"Generating Floppy Disk ${Disk}..." "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) 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
{ [byte[]]$SysImg = [System.IO.File]::ReadAllBytes($SysFile) }
else
{ [byte[]]$SysImg = @() }
$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++) for ($Usr=0; $Usr -lt 16; $Usr++)
{ {
if (Test-Path ("d_${Disk}/u${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 $Cmd
Invoke-Expression $Cmd Invoke-Expression $Cmd
} }
@ -54,7 +49,7 @@ if (Test-Path("d_${Disk}.txt"))
$Spec = $Line.Trim() $Spec = $Line.Trim()
if (($Spec.Length -gt 0) -and ($Spec.Substring(0,1) -ne "#")) if (($Spec.Length -gt 0) -and ($Spec.Substring(0,1) -ne "#"))
{ {
$Cmd = "cpmcp -f $Fmt $ImgFile ${Spec}"
$Cmd = "cpmcp -f $Format $ImgFile ${Spec}"
$Cmd $Cmd
Invoke-Expression $Cmd Invoke-Expression $Cmd
} }
@ -63,7 +58,6 @@ if (Test-Path("d_${Disk}.txt"))
"Moving image $ImgFile into output directory..." "Moving image $ImgFile into output directory..."
#&$env:COMSPEC /c move $ImgFile ..\..\Binary\
Move-Item $ImgFile -Destination "..\..\Binary\" -Force Move-Item $ImgFile -Destination "..\..\Binary\" -Force
return return

53
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' $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' $CpmToolsPath = '../../Tools/cpmtools'
@ -13,35 +23,31 @@ $env:PATH = $CpmToolsPath + ';' + $env:PATH
if (-not (Test-Path("d_${Disk}/"))) 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 return
} }
"Generating Hard Disk ${Disk}..." "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) 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
{ [byte[]]$SysImg = [System.IO.File]::ReadAllBytes($SysFile) }
else
{ [byte[]]$SysImg = @() }
$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++) for ($Usr=0; $Usr -lt 16; $Usr++)
{ {
if (Test-Path ("d_${Disk}/u${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 $Cmd
Invoke-Expression $Cmd Invoke-Expression $Cmd
} }
@ -54,7 +60,7 @@ if (Test-Path("d_${Disk}.txt"))
$Spec = $Line.Trim() $Spec = $Line.Trim()
if (($Spec.Length -gt 0) -and ($Spec.Substring(0,1) -ne "#")) if (($Spec.Length -gt 0) -and ($Spec.Substring(0,1) -ne "#"))
{ {
$Cmd = "cpmcp -f $Fmt $ImgFile ${Spec}"
$Cmd = "cpmcp -f $Format $ImgFile ${Spec}"
$Cmd $Cmd
Invoke-Expression $Cmd Invoke-Expression $Cmd
} }
@ -63,7 +69,6 @@ if (Test-Path("d_${Disk}.txt"))
"Moving image $ImgFile into output directory..." "Moving image $ImgFile into output directory..."
#&$env:COMSPEC /c move $ImgFile ..\..\Binary\
Move-Item $ImgFile -Destination "..\..\Binary\" -Force Move-Item $ImgFile -Destination "..\..\Binary\" -Force
return return

40
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

46
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 \ FDIMGS = fd_cpm22.img fd_zsdos.img fd_nzcom.img \
fd_cpm3.img fd_zpm3.img fd_ws4.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 \ HDIMGS = hd_cpm22.img hd_zsdos.img hd_nzcom.img \
hd_cpm3.img hd_zpm3.img hd_ws4.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 # 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 DEST=../../Binary
@ -19,8 +29,8 @@ include $(TOOLS)/Makefile.inc
DIFFPATH = $(DIFFTO)/Binary 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 # 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 # then process the d_{d}.txt file, copying in those files, and finally maybe put
# an OS at the start of each image # an OS at the start of each image
# #
FDSIZE := 1440
blank144: blank144:
@echo Making Blank Floppy of size 1440k
@LANG=en_US.US-ASCII tr '\000' '\345' </dev/zero | dd of=$@ bs=1024 count=1440 2>/dev/null
@echo Making Blank Floppy of size $(FDSIZE)k
@LC_CTYPE=en_US.US-ASCII tr '\000' '\345' </dev/zero | dd of=$@ bs=1024 count=$(FDSIZE) 2>/dev/null
HDSIZE := $(shell expr 128 '*' 65)
HDSIZE := 8320 # Legacy
#HDSIZE := 8192 # New
blankhd: blankhd:
@echo Making Blank Hd of size $(HDSIZE)k @echo Making Blank Hd of size $(HDSIZE)k
@LANG=en_US.US-ASCII tr '\000' '\345' </dev/zero | dd of=$@ bs=1024 count=$(HDSIZE) 2>/dev/null
@LC_CTYPE=en_US.US-ASCII tr '\000' '\345' </dev/zero | dd of=$@ bs=1024 count=$(HDSIZE) 2>/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= ; \ @sys= ; \
case $@ in \ case $@ in \
(*cpm22*) sys=../CPM22/cpm_wbw.sys;; \ (*cpm22*) sys=../CPM22/cpm_wbw.sys;; \
@ -49,8 +70,12 @@ blankhd:
esac ; \ esac ; \
if echo $@ | grep -q ^f ; then \ if echo $@ | grep -q ^f ; then \
fmt=wbw_fd144 ; type=fd_ ; proto=blank144 ; \ fmt=wbw_fd144 ; type=fd_ ; proto=blank144 ; \
mid="MID\006" ; \
else \ else \
#fmt=wbw_hd_new ; type=hd_ ; proto=blankhd ; \
#mid="MID\012" ; \
fmt=wbw_hd0 ; type=hd_ ; proto=blankhd ; \ fmt=wbw_hd0 ; type=hd_ ; proto=blankhd ; \
mid="MID\004" ; \
fi ; \ fi ; \
d=$$(echo $(basename $@) | sed s/$$type//) ; \ d=$$(echo $(basename $@) | sed s/$$type//) ; \
echo Generating $@ ; \ echo Generating $@ ; \
@ -59,6 +84,7 @@ blankhd:
echo copying system $$sys to $@ ; \ echo copying system $$sys to $@ ; \
$(BINDIR)/mkfs.cpm -f $$fmt -b $$sys $@ ; \ $(BINDIR)/mkfs.cpm -f $$fmt -b $$sys $@ ; \
fi ; \ 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 \ for u in $$(seq 0 15) ; do \
dir=d_$$d/u$$u ; \ dir=d_$$d/u$$u ; \
if [ -d $$dir ] ; then \ if [ -d $$dir ] ; then \
@ -93,7 +119,7 @@ imgdiff:
if echo $$i | grep -q ^f ; then \ if echo $$i | grep -q ^f ; then \
fmt=wbw_fd144 ; \ fmt=wbw_fd144 ; \
else \ else \
fmt=wbw_hd0 ; \
fmt=wbw_hd0_1024 ; \
fi ; \ fi ; \
$(BINDIR)/cpmls -i -f $$fmt $$i > $$i.ls ; \ $(BINDIR)/cpmls -i -f $$fmt $$i > $$i.ls ; \
$(BINDIR)/cpmls -i -f $$fmt $(DIFFPATH)/$$i > $$i.diff.ls ; \ $(BINDIR)/cpmls -i -f $$fmt $(DIFFPATH)/$$i > $$i.diff.ls ; \

139
Source/Images/diskdefs

@ -297,121 +297,158 @@ diskdef wbw_rom1024
os 2.2 os 2.2
end 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 seclen 512
tracks 12
sectrk 64
tracks 160
sectrk 18
blocksize 2048 blocksize 2048
maxdir 256 maxdir 256
skew 0 skew 0
boottrk 0
boottrk 2
os 2.2 os 2.2
end 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 seclen 512
tracks 28
sectrk 64
tracks 160
sectrk 15
blocksize 2048 blocksize 2048
maxdir 256 maxdir 256
skew 0 skew 0
boottrk 0
boottrk 2
os 2.2 os 2.2
end 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 diskdef wbw_hd0
seclen 512 seclen 512
tracks 65
sectrk 256
tracks 1040
sectrk 16
blocksize 4096 blocksize 4096
maxdir 512 maxdir 512
skew 0 skew 0
boottrk 1
boottrk 16
os 2.2 os 2.2
end end
diskdef wbw_hd1 diskdef wbw_hd1
seclen 512 seclen 512
tracks 130
sectrk 256
tracks 2080
sectrk 16
blocksize 4096 blocksize 4096
maxdir 512 maxdir 512
skew 0 skew 0
boottrk 66
boottrk 1056
os 2.2 os 2.2
end end
diskdef wbw_hd2 diskdef wbw_hd2
seclen 512 seclen 512
tracks 195
sectrk 256
tracks 3120
sectrk 16
blocksize 4096 blocksize 4096
maxdir 512 maxdir 512
skew 0 skew 0
boottrk 131
boottrk 2096
os 2.2 os 2.2
end end
diskdef wbw_hd3 diskdef wbw_hd3
seclen 512 seclen 512
tracks 260
sectrk 256
tracks 4160
sectrk 16
blocksize 4096 blocksize 4096
maxdir 512 maxdir 512
skew 0 skew 0
boottrk 196
boottrk 3136
os 2.2 os 2.2
end 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 seclen 512
tracks 160
sectrk 9
blocksize 2048
maxdir 128
tracks 1024
sectrk 16
blocksize 4096
maxdir 1024
skew 0 skew 0
boottrk 4
boottrk 2
os 2.2 os 2.2
end 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 seclen 512
tracks 160
sectrk 18
blocksize 2048
maxdir 256
tracks 1040
sectrk 16
blocksize 4096
maxdir 1024
skew 0 skew 0
boottrk 2
boottrk 18
os 2.2 os 2.2
end end
# RomWBW 360K floppy media
diskdef wbw_fd360
diskdef wbw_hd1_new
seclen 512 seclen 512
tracks 80
sectrk 9
blocksize 2048
maxdir 128
tracks 2064
sectrk 16
blocksize 4096
maxdir 1024
skew 0 skew 0
boottrk 4
boottrk 1042
os 2.2 os 2.2
end end
# RomWBW 1.20M floppy media
diskdef wbw_fd120
diskdef wbw_hd2_new
seclen 512 seclen 512
tracks 160
sectrk 15
blocksize 2048
maxdir 256
tracks 3112
sectrk 16
blocksize 4096
maxdir 1024
skew 0 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 os 2.2
end end

BIN
Source/Images/hd_prefix.dat

Binary file not shown.

4
Source/ver.inc

@ -1,5 +1,5 @@
#DEFINE RMJ 3 #DEFINE RMJ 3
#DEFINE RMN 1 #DEFINE RMN 1
#DEFINE RUP 0
#DEFINE RUP 1
#DEFINE RTP 0 #DEFINE RTP 0
#DEFINE BIOSVER "3.1-pre.16"
#DEFINE BIOSVER "3.1.1-pre.0"

4
Source/ver.lib

@ -1,7 +1,7 @@
rmj equ 3 rmj equ 3
rmn equ 1 rmn equ 1
rup equ 0
rup equ 1
rtp equ 0 rtp equ 0
biosver macro biosver macro
db "3.1-pre.16"
db "3.1.1-pre.0"
endm endm

139
Tools/cpmtools/diskdefs

@ -297,121 +297,158 @@ diskdef wbw_rom1024
os 2.2 os 2.2
end 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 seclen 512
tracks 12
sectrk 64
tracks 160
sectrk 18
blocksize 2048 blocksize 2048
maxdir 256 maxdir 256
skew 0 skew 0
boottrk 0
boottrk 2
os 2.2 os 2.2
end 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 seclen 512
tracks 28
sectrk 64
tracks 160
sectrk 15
blocksize 2048 blocksize 2048
maxdir 256 maxdir 256
skew 0 skew 0
boottrk 0
boottrk 2
os 2.2 os 2.2
end 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 diskdef wbw_hd0
seclen 512 seclen 512
tracks 65
sectrk 256
tracks 1040
sectrk 16
blocksize 4096 blocksize 4096
maxdir 512 maxdir 512
skew 0 skew 0
boottrk 1
boottrk 16
os 2.2 os 2.2
end end
diskdef wbw_hd1 diskdef wbw_hd1
seclen 512 seclen 512
tracks 130
sectrk 256
tracks 2080
sectrk 16
blocksize 4096 blocksize 4096
maxdir 512 maxdir 512
skew 0 skew 0
boottrk 66
boottrk 1056
os 2.2 os 2.2
end end
diskdef wbw_hd2 diskdef wbw_hd2
seclen 512 seclen 512
tracks 195
sectrk 256
tracks 3120
sectrk 16
blocksize 4096 blocksize 4096
maxdir 512 maxdir 512
skew 0 skew 0
boottrk 131
boottrk 2096
os 2.2 os 2.2
end end
diskdef wbw_hd3 diskdef wbw_hd3
seclen 512 seclen 512
tracks 260
sectrk 256
tracks 4160
sectrk 16
blocksize 4096 blocksize 4096
maxdir 512 maxdir 512
skew 0 skew 0
boottrk 196
boottrk 3136
os 2.2 os 2.2
end 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 seclen 512
tracks 160
sectrk 9
blocksize 2048
maxdir 128
tracks 1024
sectrk 16
blocksize 4096
maxdir 1024
skew 0 skew 0
boottrk 4
boottrk 2
os 2.2 os 2.2
end 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 seclen 512
tracks 160
sectrk 18
blocksize 2048
maxdir 256
tracks 1040
sectrk 16
blocksize 4096
maxdir 1024
skew 0 skew 0
boottrk 2
boottrk 18
os 2.2 os 2.2
end end
# RomWBW 360K floppy media
diskdef wbw_fd360
diskdef wbw_hd1_new
seclen 512 seclen 512
tracks 80
sectrk 9
blocksize 2048
maxdir 128
tracks 2064
sectrk 16
blocksize 4096
maxdir 1024
skew 0 skew 0
boottrk 4
boottrk 1042
os 2.2 os 2.2
end end
# RomWBW 1.20M floppy media
diskdef wbw_fd120
diskdef wbw_hd2_new
seclen 512 seclen 512
tracks 160
sectrk 15
blocksize 2048
maxdir 256
tracks 3112
sectrk 16
blocksize 4096
maxdir 1024
skew 0 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 os 2.2
end end

Loading…
Cancel
Save