From dc6ecfd9e3fbad91593439867a4fa8376e675777 Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Sun, 17 Nov 2019 17:35:11 -0800 Subject: [PATCH] CP/M 3 Support in ASSIGN --- Source/Apps/Assign.asm | 178 ++++++++++++++++++++++++++++++++++++++++- Source/CBIOS/cbios.asm | 6 +- Source/HBIOS/hbios.asm | 11 ++- 3 files changed, 190 insertions(+), 5 deletions(-) diff --git a/Source/Apps/Assign.asm b/Source/Apps/Assign.asm index 129de63d..e76adab7 100644 --- a/Source/Apps/Assign.asm +++ b/Source/Apps/Assign.asm @@ -21,11 +21,13 @@ ; 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: ; 1) Do something to prevent assigning slices when device does not support them ; 2) ASSIGN C: causes drive map to be reinstalled unnecessarily +; 3) Need to find a way to verify RomWBW under CP/M 3 ;_______________________________________________________________________________ ; ;=============================================================================== @@ -47,6 +49,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 +99,14 @@ 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? + jp nc,initcpm3 ; handle CP/M 3.0 or greater ; ; get location of config data and verify integrity ld hl,stamp ; HL := adr or RomWBW zero page stamp @@ -193,6 +216,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 +457,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 +712,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 +1794,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 +1862,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 +1889,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..a1b5320e 100644 --- a/Source/CBIOS/cbios.asm +++ b/Source/CBIOS/cbios.asm @@ -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/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