diff --git a/Source/Apps/Assign.asm b/Source/Apps/Assign.asm index 129de63d..28a950ba 100644 --- a/Source/Apps/Assign.asm +++ b/Source/Apps/Assign.asm @@ -21,6 +21,7 @@ ; 2016-03-21 [WBW] Updated for HBIOS 2.8 ; 2016-04-08 [WBW] Determine key memory addresses dynamically ; 2019-08-07 [WBW] Fixed DPB selection error +; 2019-11-17 [WBW] Added preliminary CP/M 3 support ;_______________________________________________________________________________ ; ; ToDo: @@ -47,6 +48,19 @@ rmn .equ 9 ; CBIOS version - minor ;=============================================================================== ; .org $100 +; + ; relocate to high memory + ld hl,image + ld de,$8000 + ld bc,modsize + ldir + jp start +; +image .equ $ +; + .org $8000 +; +start: ; ; setup stack (save old value) ld (stksav),sp ; save stack @@ -84,6 +98,13 @@ init: ld de,-3 ; adjustment for start of table add hl,de ; HL now has start of table ld (bioloc),hl ; save it +; + ; get CP/M version and save it + ld c,$0C ; function number + call bdos ; do it, HL := version + ld (cpmver),hl ; save it + ld a,l ; low byte + cp $30 ; CP/M 3.0? ; ; get location of config data and verify integrity ld hl,stamp ; HL := adr or RomWBW zero page stamp @@ -123,6 +144,11 @@ init: inc hl ; ... into DE to get ld d,(hl) ; ... DPB map pointer ld (dpbloc),de ; and save it +; + ; test for CP/M 3 and branch if so + ld a,(cpmver) ; low byte of cpm version + cp $30 ; CP/M 3.0? + jp nc,initcpm3 ; handle CP/M 3.0 or greater ; ; make a local working copy of the drive map ld hl,(maploc) ; copy from CBIOS drive map @@ -193,6 +219,66 @@ initx: xor a ; signal success ret ; return ; +; CP/M 3 initialization +; +initcpm3: + ld hl,(bioloc) + ld de,22*3 ; offset of DRVTBL func + add hl,de ; HL := DRVTBL func + call jphl ; do it, HL := DRVTBL adr + ld (drvtbl),hl ; save it +; + ; switch to sysbnk + ld hl,(bioloc) + ld de,27*3 ; offset of SELMEM func + add hl,de ; HL := SELMEM func + ld a,0 ; bank 0 is system bank + call jphl +; + ; copy CP/M 3 drvtbl to drvmap working copy + ld hl,(drvtbl) ; get drive table in HL + ld de,mapwrk ; DE := working drive map + ld b,16 +initc2: + push hl ; save drvtbl entry adr + ld a,(hl) ; deref HL to get DPH adr + inc hl ; ... + ld h,(hl) ; ... + ld l,a ; ... + ld a,l ; check for + or h ; ... zero + jr nz,initc3 ; if not zero, copy entry + inc de ; ... else bump past unit field + jr initc4 ; ... and continue without copying +initc3: + dec hl ; back up to + dec hl ; ... unit + ld a,(hl) ; get unit from drvtbl + ld (de),a ; save unit to drvmap + inc hl ; bump to slice + inc de ; bump to slice + ld a,(hl) ; get slice from drvtbl + ld (de),a ; save slice to drvmap +initc4: + inc de ; bump past slice + inc de ; skip + inc de ; ... dph + pop hl ; back to drvtbl entry + inc hl ; bump to + inc hl ; ... next drvtbl entry + djnz initc2 +; + ; switch back to tpabnk + ld hl,(bioloc) + ld de,27*3 ; offset of SELMEM func + add hl,de ; HL := SELMEM func + ld a,1 ; bank 1 is tpa bank + call jphl +; + ; return success + xor a ; signal success + ret ; return +; ; Process command line ; process: @@ -374,6 +460,10 @@ devlstu1: ; Install the new drive map into CBIOS ; install: + ld a,(cpmver) ; low byte of CP/M version + cp $30 ; CP/M 3.0? + jp nc,instcpm3 ; handle CP/M 3.0 or greater +; ; capture CBIOS snapshot and stack frame for error recovery ld hl,(bioloc) ; start of CBIOS ld de,$8000 ; save it here @@ -625,6 +715,90 @@ makdph3: xor a ; signal success ret ; +; +; +instcpm3: +; + ; switch to sysbnk + ld hl,(bioloc) + ld de,27*3 ; offset of SELMEM func + add hl,de ; HL := SELMEM func + ld a,0 ; bank 0 is system bank + call jphl +; + ; copy drvmap working copy to CP/M 3 drvtbl + ld hl,(drvtbl) ; get drvtbl address + ld a,(hl) ; deref HL to get DPH0 adr + inc hl ; ... + ld h,(hl) ; ... + ld l,a ; ... + ld (dphadr),hl ; save starting dphadr + + + ld hl,(drvtbl) ; get drive table in HL + ld de,mapwrk ; DE := working drive map + ld b,16 +instc1: + ld a,(de) ; get unit field of mapwrk + inc a ; test for $FF + jr nz,instc2 ; if used, do copy + xor a ; zero accum + ld (hl),a ; zero lsb of drvtbl entry adr + inc hl ; move to msb + ld (hl),a ; zero msb of drvtbl entry adr + inc hl ; bump to start of next drvtbl entry + inc de ; bump to next mapwrk entry + inc de ; ... + inc de ; ... + inc de ; ... + jr instc3 ; resume loop without copy +; +instc2: + push hl ; save drvtbl entry adr + push de ; save mapwrk entry adr + ld de,(dphadr) ; get cur dph adr + ld (hl),e ; save dph adr to drvtbl + inc hl ; ... + ld (hl),d ; ... + ex de,hl ; dph adr to HL + pop de ; restore mapwrk entry adr + dec hl ; backup to unit + dec hl ; ... + ld a,(de) ; get unit from mapwrk + ld (hl),a ; put unit into DPH field + inc de ; bump to slice field of mapwrk + inc hl ; bump to slice field of DPH field + ld a,(de) ; get slice from mapwrk + ld (hl),a ; put slice into DPH field + inc de ; bump to next mapwrk entry + inc de ; ... + inc de ; ... + pop hl ; back to drvtbl entry + inc hl ; bump to + inc hl ; ... next drvtbl entry +instc3: + push hl ; save drvtbl entry adr + push de ; save mapwrk entry adr + ld hl,(dphadr) ; get cur dph address + ld de,$23 ; size of xdph + add hl,de ; bump to next dph + ld (dphadr),hl ; save it + pop de ; recover mapwrk entry adr + pop hl ; recover drvtbl entry adr + djnz instc1 +; + ; switch back to tpabnk + ld hl,(bioloc) + ld de,27*3 ; offset of SELMEM func + add hl,de ; HL := SELMEM func + ld a,1 ; bank 1 is tpa bank + call jphl +; + call drvrst ; perform BDOS drive reset +; + xor a ; signal success + ret +; ; Handle overflow error in installation ; instovf: @@ -1623,6 +1797,9 @@ bioend .dw 0 ; CBIOS ending address biosiz .dw 0 ; CBIOS size (in bytes) maploc .dw 0 ; location of CBIOS drive map table dpbloc .dw 0 ; location of CBIOS DPB map table +cpmver .dw 0 ; CP/M version +drvtbl .dw 0 ; CP/M 3 drive table address +dphadr .dw 0 ; CP/M 3 working value for DPH ; drives: dstdrv .db 0 ; destination drive @@ -1688,7 +1865,7 @@ stack .equ $ ; stack top ; Messages ; indent .db " ",0 -msgban1 .db "ASSIGN v1.0d for RomWBW CP/M 2.2, 08-Aug-2019",0 +msgban1 .db "ASSIGN v1.1 for RomWBW CP/M, 17-Nov-2019",0 msghb .db " (HBIOS Mode)",0 msgub .db " (UBIOS Mode)",0 msgban2 .db "Copyright 2019, Wayne Warthen, GNU GPL v3",0 @@ -1715,5 +1892,7 @@ msgint .db "Multiple drive letters reference one filesystem, aborting!",0 msgnoa .db "Drive A: is unassigned, aborting!",0 msgdos .db "DOS error, return code=0x",0 msgmem .db " Disk Buffer Bytes Free",0 +; +modsize .equ $ - start ; .end diff --git a/Source/CBIOS/cbios.asm b/Source/CBIOS/cbios.asm index afcd5bab..971d3690 100644 --- a/Source/CBIOS/cbios.asm +++ b/Source/CBIOS/cbios.asm @@ -131,7 +131,7 @@ STPSIZ .EQU $ - STPIMG ; ; The following section contains key information and addresses for the ; RomWBW CBIOS. A pointer to the start of this section is stored with -; with the ZPX data in page zero at $44 (see above). +; with the CBX data in page zero at $44 (see above). ; CBX: DEVMAPADR .DW DEVMAP ; DEVICE MAP ADDRESS @@ -237,7 +237,7 @@ DEVMAP: ; Disk mapping is done using a drive map table (DRVMAP) which is built ; dynamically at cold boot. See the DRV_INIT routine. This table is ; made up of entries as documented below. The table is prefixed with one -; byte indicating the number of entries. The postion of the entry indicates +; byte indicating the number of entries. The position of the entry indicates ; the drive letter, so the first entry is A:, the second entry is B:, etc. ; ; UNIT: BIOS DISK UNIT # (BYTE) @@ -272,8 +272,8 @@ DEVMAP: ; DPB MAPPING TABLE ;================================================================================================== ; -; MAP MEDIA ID'S TO APPROPRIATE DPB ADDRESSEES -; THE ENTRIES IN THIS TABLE MUST CONCIDE WITH THE VALUES +; MAP MEDIA ID'S TO APPROPRIATE DPB ADDRESSES +; THE ENTRIES IN THIS TABLE MUST COINCIDE WITH THE VALUES ; OF THE MEDIA ID'S (SAME SEQUENCE, NO GAPS) ; .DB DPBCNT diff --git a/Source/CPM3/boot.z80 b/Source/CPM3/boot.z80 index 0e8b1013..a870edea 100644 --- a/Source/CPM3/boot.z80 +++ b/Source/CPM3/boot.z80 @@ -12,6 +12,8 @@ extrn dph0 extrn @dtbl,@ctbl + include ver.inc + bdos equ 5 if banked @@ -25,14 +27,11 @@ tpa$bank equ 0 ?init: call ?mvinit - ; Clear reserved area in page zero - xor a - ld hl,40h - ld b,10h -init$1: - ld (hl),a - inc hl - djnz init$1 + ; Install RomWBW CBIOS stamp in page zero + ld hl,stpimg + ld de,stploc + ld bc,stpsiz + ldir if banked @@ -382,12 +381,13 @@ read: ld c,20 jp bdos - signon$msg db 13,10,'CP/M v3.0' if banked db ' [BANKED]' endif - db ' for RomWBW HBIOS v2.9.2',13,10,13,10,0 + db ' on HBIOS v' + biosver + db 13,10,13,10,0 ccp$msg db 13,10,'BIOS Err on ' ccp$msg$drv db '?' @@ -401,4 +401,27 @@ fcb$nr db 0,0,0 @bootdu db 0 hdspv db 2 ; slices per volume for hard disks (must be >= 1) +; RomWBW CBIOS page zero stamp starts at $40 +; $40-$41: Marker ('W', ~'W') +; $42-$43: Version bytes: major/minor, update/patch +; $44-$45: CBIOS Extension Info address +; +stploc equ 40h +stpimg db 'W',~'W' ; marker + db rmj << 4 | rmn ; first byte of version info + db rup << 4 | rtp ; second byte of version info + dw cbx ; address of cbios ext data +stpsiz equ $ - stpimg + +; +; The following section contains key information and addresses for the +; RomWBW CBIOS. A pointer to the start of this section is stored with +; with the CBX data in page zero at $44 (see above). +; +cbx: +devmapadr dw 0 ; device map address +drvtbladr dw @dtbl ; drive map address (filled in later) +dphtbladr dw dph0 ; dpb map address +cbxsiz equ $ - cbx +; end diff --git a/Source/CPM3/ver.inc b/Source/CPM3/ver.inc new file mode 100644 index 00000000..379d1cd7 --- /dev/null +++ b/Source/CPM3/ver.inc @@ -0,0 +1,7 @@ +rmj equ 2 +rmn equ 9 +rup equ 2 +rtp equ 0 +biosver macro + db "2.9.2-pre.21" + endm diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index b990716a..b17a35ca 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -775,6 +775,12 @@ HB_START: OUT0 (Z180_TCR),A ; SET DEFAULT CPU CLOCK MULTIPLIERS (XTAL / 2) + ; + ; IT HAS BEEN REPORTED THAT CMR NEEDS TO BE SET PRIOR TO CCR + ; SEEMS COUNTER-INTUITIVE AND I NEVER EXPERIENCED A PROBLEM + ; RELATED TO ORDER, BUT JUST FOR GOOD MEASURE, CMR + ; IS SET PRIOR TO CCR BELOW. + ; https://www.retrobrewcomputers.org/forum/index.php?t=msg&th=316&#msg_5045 XOR A OUT0 (Z180_CMR),A OUT0 (Z180_CCR),A @@ -1008,8 +1014,11 @@ HB_CPU1: CP 3 ; Z8S180 REV N OR BETTER? JR C,HB_CPU2 ; IF NOT, NOT POSSIBLE! ; SET CPU MULTIPLIER TO 1 RESULTING IN XTAL * 2 SPEED + ; ALSO SET CCR AGAIN BECAUSE OF REPORTS THAT CCR + ; *MUST* BE SET AFTER CMR. LD A,$80 - OUT0 (Z180_CMR),A + OUT0 (Z180_CMR),A ; CPU MULTIPLIER + OUT0 (Z180_CCR),A ; CLOCK DIVIDE ; REFLECT SPEED CHANGE LD C,(CPUOSC * 2) / 1000000 LD DE,(CPUOSC * 2) / 1000