TITLE "SPEEDLDR.Z80 - Loader for SPEED.Z80, 19 Aug 89" ;======================================================================= ; Load the SPEEDUP Module as an RSX. ; This module performs pre-load checks, environment validation, and ; calculated various calculations to load the SPEED Directory Buffer ; program. If validated, it relocated the core routine to high memory ; for execution. ; Harold F. Bower ; P.O. Box 313 ; Ft. Meade, MD 20755 ; ; Portions of the code were derived from LOADBGPR.ASM updated with new ; standards as detailed in TCJ Issue #34 by Bridger Mitchell ; ; Plu*Perfect Systems ; 410 23d Street ; Santa Monica, CA 90402 ;======================================================================= VERS EQU 12 ; Version number REV EQU ' ' ; Revision level ;....... ; History. ; 19 Aug 89 12. Changed to correct Page 0 PRL word location. HFB ; 11 Aug 89 11. Modified to use extended ZCPR3 Environment. HFB ; 10 Mar 89 10. Added Configurability of Warm Boot Message. HFB ; 15 Jan 89 01a. Changed to "New" Standard RSX header, RSX standard ; module configuration from 1982-86 working versions ;....... ; General equates. BELL EQU 7 LF EQU 10 CR EQU 13 ; CP/M Standard values and locations. BDOS EQU 0005H ; Vector addr to CP/M FCB EQU 005CH ; Default CP/M File Control Block BDOSLEN EQU 0E00H ; Length of BDOS ; Offsets from base of permanent module for module header ORSXWB EQU 9 ; Word - Original 0001,2 value ONAME EQU 0DH ; Word - Ptr to RSX Name ORSXNX EQU 0FH ; Jump Next WB or CCP Entry ONXTWB EQU 15H ; Jump Orig BIOS+4 Address ; No ORG needed if assembling with standard .REL tools to create ; COM file executing at 100H ENTER: JP START DEFB 'Z3ENV' ; Appear as ZCPR3 Utility DEFB 1 Z3EADR: DEFW 0FE00H ; Place holder in ZCPR 3.3 or later ;******************************************************************* ; Configuration-related items placed early in header for location DEFW 0000 ; ZCPR 3.4 pad bytes to place name DEFB 'SPEEDUP ',0 ; Look for .CFG file of this name ; Flag to control printing of SPEEDUP Warm Boot Message WBMSG: DEFB 0FFH ; 0 = No Print, FF = Print WB Message ; Size of Console Command Processor (for Non-standard installations) CCPSIZ: DEFW 0800H ; Size of CCP in bytes ;******************************************************************* START: LD (STACK),SP LD SP,STACK LD HL,FCB+1 ; See if HELP wanted LD A,(HL) INC HL AND (HL) ; ..two slashes for help CP '/' JR NZ,START0 ; Load module if not HELP request LD DE,HELP ; Print help message.. ABORT: CALL PRINT ; Print message in DE and abort LD SP,(STACK) RET START0: CALL SIGNON CALL CKENV ; check runtime environment LD A,(WBMSG) ; Move the WB message flag LD (RSXFLG),A ; ..to module CALL INSTAL ; Do the installation and move module LD HL,(OFFSET) ; Jump to high module JP (HL) ;---------------------------------------- ; check the system environment before loading CKENV: CALL TSTLOW ; Any modules below the Bdos now? RET C ; ..return if not, nothing to test CALL TSTTMP ; Is there a temporary module? LD DE,TMPMSG ; ..(prepare for error) JR NZ,ABORT ; ...jump error if so CALL FINDMO ; Compare ID name up the RSX trail LD DE,DUPMSG JR NC,ABORT ; ..jump Dupe error if matched RET ; Else not found, ready to install ;..... ; CY clear if memory is protected below the bdos. ; set system addresses when checking. TSTLOW: LD HL,(0001H) LD (RSXWBA),HL ; Patch load linkage record LD L,00 LD (BIOBAS),HL ; Save start of BIOS Jump table PUSH HL EX DE,HL ; Calculate offset to CCP base LD HL,(Z3EADR) ; Get any ENV address LD A,H OR L ; Anything there? JR Z,TSTLO2 ; ..jump to calculate if not LD BC,8 ; Else offset to Extended byte ADD HL,BC BIT 7,(HL) ; Is it extended? JR Z,TSTLO2 ; ..jump to calculate if not LD BC,3FH-8 ; Offset to CCP addr in Extended Env ADD HL,BC LD A,(HL) ; ..and get it to HL INC HL LD H,(HL) LD L,A JR TSTLO3 ; Continue with tests TSTLO2: LD BC,BDOSLEN LD HL,(CCPSIZ) ADD HL,BC EX DE,HL OR A SBC HL,DE TSTLO3: LD (CCPBAS),HL ; Save calculated CCP Base address POP HL LD L,4 LD A,(HL) ; check that no temp module below CCP INC HL LD H,(HL) LD L,A LD (NEXTWB),HL LD A,(0002) ; Does jump point below the BIOS? DEC A ; In case Warmboot on 1st page of BIOS CP H RET ; CY clear if something below ;..... ; NZ if a non-permanent (non-standard) module active below ccp ; e.g. DDT, EX TSTTMP: LD HL,(NEXTWB) LD DE,6+2 ; 2 jmps, 1 word, point at protect addr ADD HL,DE LD E,(HL) INC HL LD D,(HL) LD HL,(0006H) ; If same as BDOS jump, this is perm. module OR A SBC HL,DE RET ; ..NZ if transient module ;..... ; See if this module is already loaded ; Exit : CY clear if found FINDMO: LD HL,(0001H) INC HL ; Point at WB addr in BIOS jmp vector FINDM1: LD A,(HL) ; ..and load argument INC HL LD H,(HL) LD L,A EX DE,HL LD HL,(0001H) ; If (HL=Bios+4) < Addr OR A SBC HL,DE EX DE,HL RET C ; ..exit if Not found PUSH HL LD DE,ONAME-3 ; Else offset to Name pointer ADD HL,DE LD E,(HL) ; ..load address of ID string INC HL LD D,(HL) CALL VERIFY ; Does it match request? POP HL JR NZ,FINDM2 ; ..jump if Not found and check more DEC HL ; Else back down if Found DEC HL DEC HL OR A ; Clear Carry status for Found Error RET FINDM2: LD DE,ORSXNX+1-3 ; Move up to next module ADD HL,DE JR FINDM1 ;..... ; String compare utility routine ; Enter: DE = Module string to check ; Exit : NZ if mismatch VERIFY: LD B,IDLEN ; Set string length LD HL,IDNAM ; ..and name string VERLOP: LD A,(DE) ; Compare chars til null or no match CP (HL) INC HL INC DE RET NZ DJNZ VERLOP ; ..loop til done RET ;..... ; Perform actual relocation and final parameter setup INSTAL: LD HL,(BIOBAS) ; Copy the BIOS Jump table to local LD DE,OBIOS LD BC,32H LDIR ; Assume module to be loaded has parms at protect address, not higher XOR A ; Preset flag for CCP protect LD HL,(0006H) ; Check for protect addr below CCP PUSH HL LD DE,(CCPBAS) SBC HL,DE POP HL JR C,INST1A ; ..jump if protected and use BDOS vector EX DE,HL ; Else protect the CCP DEC A ; Flag this by setting 0FFH INST1A: LD (GOCCP),A LD DE,(SIZE) ; Subtract length of code OR A SBC HL,DE LD (OFFSET),HL ; Save Addr for execution start PUSH HL ; Save address.. ; Insert warm boot vector in place in linkage header. (revised sequence) LD HL,(OBIOS+03H+1) ; Install upper warmboot addr LD A,(GOCCP) ; unless it's the top module OR A JR Z,INSTW1 LD HL,(CCPBAS) ; in which case install CCP entry INC HL INC HL INC HL INSTW1: LD (RSXNXT+1),HL ; Relocate module code and move module to final address. POP DE ; Restore Target Address of module LD BC,(SIZE) ; Load Module Size from PRL Header LD HL,CODE ; Point to Base of Code to relocate DI ; No interrupts here PUSH DE ; Save destination addr PUSH BC ; ..and Byte Count LD C,E ; ..move to BC for offset LD B,D DEC B ; Compensate for 100H Org in PRL file PUSH HL ; Save Source address EXX ; Switch to Alternate reg set POP HL ; Source addr to HL' POP DE ; Code Size to DE' PUSH DE ; ..keep values on stack PUSH HL ADD HL,DE ; Resulting HL' has Bit Map Start addr RELOC0: LD A,D ; ..DE' Has number of bytes left in Code OR E ; Done w/relocation? EXX ; ..back to primary regs JR Z,RELDON ; Exit if finished LD A,L ; Do we need a new Map Byte? AND 07H JR NZ,NXTBYT ; ..jump if not EXX ; Else go to Alternate Regs LD C,(HL) ; ..to get a new Map Byte (C' is Map Byte) INC HL ; Point to next EXX ; ..back to primary Regs NXTBYT: EXX ; Alternate regs for relocation check RL C ; Shift out next Map Bit EXX JR NC,RELOC1 ; Jump if no relocation needed LD D,(HL) ; Else get Hi-byte for relocation DEC HL LD E,(HL) ; ..and low in case base not page aligned EX DE,HL ; Swap for 16-bit add ADD HL,BC ; Add in offset EX DE,HL LD (HL),E ; Save relocated address INC HL LD (HL),D RELOC1: INC HL ; Point to next code byte EXX ; Go to Alternate regs for checks DEC DE ; Count down JR RELOC0 ; ..and loop RELDON: POP HL ; Restore source POP BC ; .count POP DE ; ..and destination LDIR ; Move the module EI ; Interrupts now allowed RET ;..... ; Message Handler and text strings SIGNON: LD DE,BANNER PRINT: LD C,9 JP BDOS DUPMSG: DEFB CR,LF,'Module is already loaded.$' TMPMSG: DEFB CR,LF,BELL,'Non-permanent module active!$' HELP: DEFB LF,LF,'SPEEDUP V',VERS/10+'0','.',VERS MOD 10+'0',REV,' ' DEFB 'Disk Cache Buffer RSX by H.F.Bower',CR,LF,LF DEFB ' Syntax:',CR,LF DEFB ' SPEEDUP [d:][s]',CR,LF DEFB ' Options:',CR,LF DEFB ' d: - Drive letter followed by colon',CR,LF DEFB ' s - Size of cache in K (1-8)',CR,LF DEFB ' Defaults:',CR,LF DEFB ' Drive is currently logged',CR,LF DEFB ' Size is 4K (128 entries)',CR,LF DEFB ' Examples:',CR,LF DEFB ' SPEEDUP - Cache 4K of current drive',CR,LF DEFB ' SPEEDUP 6 - Cache 6K of current drive',CR,LF DEFB ' SPEEDUP D: - Cache 4K of drive D:',CR,LF DEFB ' SPEEDUP C:8 - Cache 8K of drive C:',CR,LF,'$' BANNER: DEFB CR,LF DEFB 'SPEEDUP Loader, V ',VERS/10+'0','.',VERS MOD 10+'0',REV DEFB ' by H.F.Bower',CR,LF,'$' IDNAM: DEFB 'SPEEDUP' IDLEN EQU $-IDNAM ;************************************************************ ; Data Area for Loader GOCCP: DEFB 0 ; NZ if module should jump to CCP entry OFFSET: DEFW 0 ; Base of module in high memory BIOBAS: DEFW 0 ; Base of BIOS jmp table (on Entry) CCPBAS: DEFW 0 ; Base of CCP (calculated from BiosBase) OBIOS: DEFS 33H ; Copy of original BIOS jump table DEFS 48 ; Loader's stack STACK: DEFS 2 DEFS 100H-[[$-ENTER] MOD 256] ; Load PRL on page boundary ;********************************************************************** ; The .PRL module goes here. It consists of a header record containing ; only a word value of the combined CSEG/DSEG code at offset 1 and 2, ; which is also the offset of the Relocation bit map in the code portion ; of the module. The code begins 100H bytes past the beginning of the ; header, and is ORG'ed at 100H. SIZE EQU $+1 ; Size word offset in by one byte CODE EQU SIZE+0FFH ; Code and Bitmap starts here ; JP 0 (ORSX) - Entry ; 00H ; JP 0 - Warm boot Intercept ; +03H ; JP 0 - Remove-RSX Entry ; +06H RSXWBA EQU CODE+ORSXWB ; Word - Original Addr at 0001,2 ; +09H ; DEFW 0 (ORSXPROT) - Lowest RSX address in this module ; +0BH ; DEFW 0 - Pointer to Name String ; +0DH RSXNXT EQU CODE+ORSXNX ; Jump - Next Warm Boot or CCP Entry ; +0FH ; ; JP 0 (NEXT) - -> Next RSX or BDOS ; +12H NEXTWB EQU CODE+ONXTWB ; Word - Original BIOS+4 Address ; +15H RSXFLG EQU NEXTWB+2 ; Byte - Flag for print of WB message ; +17H END