TITLE 'CP/M-85 BIOS RELOCATOR 06 APR 1982' ;*** ; ; CP/M-85 BIOS RELOCATOR. ; ; THIS CODE RESIDES IN THE FILE 'BIOS85.SYS' ALONG WITH THE 8085 ; CODED PORTION OF THE REAL BIOS. THE BIOS LOADER READS THE FILE ; INTO MEMORY, THEN TRANSFERS CONTROL TO THIS RELOCATOR TO PLACE ; THE 8085 CODED PORTION OF THE REAL BIOS INTO ITS PROPER SPOT ; IN MEMORY. ; REL0 EQU 0 ASM86 EQU 0 ;** EXTRA PSEUDO OPS FOR USE WITH MAC ; RB MACRO A DS A ENDM RW MACRO A DS 2*A ENDM ;*** EQUATES ; ;** Z-MACHINE MEMORY MAP UTILIZATION EQUATES ; BOOTORG EQU 0400H ;BOOT CODE LOAD ADDRESS BCODEL EQU 256+32 ;MAXIMUM BOOT CODE LENGTH BLDR88 EQU BOOTORG+BCODEL ;BIOS LOADER (8088 PORTION) BLDR88L EQU 64 ;MAXIMUM BIOS LOADER (8088) LENGTH B88STK EQU 2*1024 ;8088 STACK AREA B88DAT EQU B88STK ;MONITOR ROM DATA AREA START ADDR BIOS88 EQU 4*1024 ;WHERE 8088 CODE OF BIOS WILL RESIDE BLDRP0 EQU 16*1024 ;BIOS LOADER PAGE ZERO BIAS VALUE IF REL0 BLOADER EQU 0000H ;WHERE BOOT CODE LOADS BIOS LOADER ENDIF IF NOT REL0 BLOADER EQU 0100H ;WHERE BOOT CODE LOADS BIOS LOADER ENDIF BLDR85L EQU 8*128-BCODEL-BLDR88L ;MAXIMUM BIOS LOADER (8085) LENGTH BOOT85 EQU 0000H ;WHERE 8085 STARTS AFTER PROCESSOR SWAP SWISWAP EQU 0FEH ;SWI FOR SWAPPING PROCESSORS SWAPVEC EQU SWISWAP*4 ; VECTOR ADDRESS BIAS EQU BLDRP0 ;** CP/M-85 SYSTEM EQUATES ; ; OS VALUES CCPL EQU 0800H ;LENGTH OF CCP BDOSL EQU 0E00H ;LENGTH OF BDOS ; RESERVED LOCATIONS IN PAGE ZERO ORG BIAS BOOT RB 3 ;JUMP TO WARM START ENTRY IOBYTE RB 1 ;IOBYTE DFTDRV RB 1 ;CURRENT EFAULT DRIVE BDOS RB 3 ;JUMP TO BDOS INT1 RB 8 ;INTERRUPT LOCATION 1 INT2 RB 8 ;INTERRUPT LOCATION 2 INT3 RB 8 ;INTERRUPT LOCATION 3 INT4 RB 8 ;INTERRUPT LOCATION 4 INT5 RB 8 ;INTERRUPT LOCATION 5 INT6 RB 8 ;INTERRUPT LOCATION 6 (RESERVED) INT7 RB 8 ;INTERRUPT LOCATION 7 (USED BY DDT) BSCR RB 16 ;16 BYTE SCRATCH AREA FOR BIOS RB 12 ;12 BYTES NOT USED BUT RESERVED TFCB RB 36 ;TRANSIENT DEFAULT FCB TFCB2 EQU TFCB+16 ;TRANSIENT 2ND FILENAME TBUFF RB 128 ;DEFAULT DISK BUFFER TPA RB 0 ;START OF TRANSIENT PROGRAM AREA ; HEATH PAGE ZERO LOCATIONS IF ASM86 ORG OFFSET INT1+3 ENDIF IF NOT ASM86 ORG INT1+3 ENDIF TICCNT RW 2 ;32 BIT TIMER TIC COUNTER TIMEFLG RB 1 ;TIMER 2 FLAG (0=RUNNING , 1=TIME OUT) IF ASM86 ORG OFFSET INT2 ENDIF IF NOT ASM86 ORG INT2 ENDIF COMREG RB 0 ;BIOS88 COMMUNICATION REGION COMFUNC RB 1 ; BIOS FUNCTION VALUE = (#-CBOOT)/3 COMRA RB 1 ; (A) COMRBC RW 0 ; (BC) COMRC RB 1 ; (C) COMRB RB 1 ; (B) COMRDE RW 0 ; (DE) COMRE RB 1 ; (E) COMRD RB 1 ; (D) COMRHL RW 0 ; (HL) COMRL RB 1 ; (L) COMRH RB 1 ; (H) COMWHO RB 1 ;WHICH PROCESSOR IS RUNNING ; ZPSPPS5 = 8085 ; ZPSPPS8 = 8088 IF ASM86 ORG OFFSET INT4 + 3 ENDIF IF NOT ASM86 ORG INT4 + 3 ENDIF LPENHF RB 1 ;LIGHT PEN HIT FLAG (<>0 = HIT) LPENPOS RW 1 ;LIGHT PEN POSITION LPENHIT RB 1 ;LIGTH PEN HIT REGISTER IMAGE BDMAP EQU BSCR+00H ;DRIVE MAP (MAX OF 8 ENTRIES 0-7) IF ASM86 BBIOS EQU WORD PTR BSCR+0EH ;TRUE ADDRESS FOR START OF BIOS ENDIF IF NOT ASM86 BBIOS EQU BSCR+0EH ;TRUE ADDRESS FOR START OF BIOS ENDIF ; CP/M FUNCTIONS RESET EQU 0 ;SYSTEM RESET RDCON EQU 1 ;READ CONSOLE WRCON EQU 2 ;WRITE CONSOLE RDRDR EQU 3 ;READ READER WRPUN EQU 4 ;WRITE PUNCH WRLST EQU 5 ;WRITE LIST DCONIO EQU 6 ;DIRECT CONSOLE I/O (2) IOSTAT EQU 7 ;INTERROGATE I/O STATUS ASTAT EQU 8 ;ALTER I/O STATUS PRCONB EQU 9 ;PRINT CONSOLE BUFFER RDCONB EQU 10 ;READ CONSOLE BUFFER CCSTAT EQU 11 ;CHECK CONSOLE STATUS LDH EQU 12 ;LIFT DISK HEAD CPMVER EQU LDH ;GET CP/M VERSION (2) RDS EQU 13 ;RESET DISK SYSTEM SELDSK EQU 14 ;SELECT DISK OPEN EQU 15 ;OPEN FILE CLOSE EQU 16 ;CLOSE FILE S1ST EQU 17 ;SEARCH FIRST SNXT EQU 18 ;SEARCH NEXT DELETE EQU 19 ;DELETE FILE READ EQU 20 ;READ RECORD WRITE EQU 21 ;WRITE RECORD CREATE EQU 22 ;CREATE FILE RENAME EQU 23 ;RENAME FILE ILOG EQU 24 ;INTERROGATE LOGIN IDSK EQU 25 ;INTERROGATE DISK SETDMA EQU 26 ;SET DMA ADDRESS IALLOC EQU 27 ;INTERROGATE ALLOCATION WPD EQU 28 ;WRITE PROTECT DISK GROV EQU 29 ;GET READ/ONLY VECTOR SFA EQU 30 ;SET FILE ATTRIBUTES GADPB EQU 31 ;GET ADDR OF DPB SGUSR EQU 32 ;SET/GET USER CODE READRR EQU 33 ;READ RANDOM RECORD WRITERR EQU 34 ;WRITE RANDOM RECORD CFSIZE EQU 35 ;COMPUTE FILE SIZE SRR EQU 36 ;SET RANDOM RECORD RESDRV EQU 37 ;RESET DRIVE WRITERZ EQU 40 ;WRITE RANDOM WITH ZERO FILL ; BIOS ENTRY POINTS. ; GIVEN AS DISPLACEMENTS FROM WARM BOOT ENTRY POINT WHOSE ; ADDRESS IS USUALLY AT LOCATION BOOT+1. ; TO COMPUTE DISPLACEMENTS FROM VALUE STORED AT 'BBIOS' ; SUBTRACT 'CBOOT'. EG. DISPLACEMENT FOR WARM BOOT = WBOOT-CBOOT CBOOT EQU -0003H ;COLD BOOT WBOOT EQU 0000H ;WARM BOOT CONST EQU 0003H ;CONSOLE STATUS CONIN EQU 0006H ;CONSOLE INPUT CONOUT EQU 0009H ;CONSOLE OUTPUT LSTOUT EQU 000CH ;LIST OUTPUT PUNOUT EQU 000FH ;PUNCH OUTPUT RDRIN EQU 0012H ;READER INPUT HOME EQU 0015H ;HOME DISK SETDSK EQU 0018H ;SET (SELECT) DISK DRIVE SETTRK EQU 001BH ;SET TRACK NUMBER SETSEC EQU 001EH ;SET SECTOR NUMBER SDMA EQU 0021H ;SET DMA ADDRESS BREAD EQU 0024H ;READ SELECTED SECTOR BWRITE EQU 0027H ;WRITE SELECTED SECTOR BLSTST EQU 002AH ;CHECK LIST DEVICE STATUS BSECTRN EQU 002DH ;SECTOR TRANSLATE ROUTINE BFMT EQU 0030H ;FORMAT BRDTRK EQU 0033H ;READ TRACK BWRTRK EQU 0036H ;WRITE TRACK BWPC EQU 0039H ;WRITE PROTECT CHECK BCBD EQU 003CH ;CLEAR BUFFERS FOR DRIVE BPEEK EQU 003FH ;PEEK 8088 MEMORY FUNCTION BPOKE EQU 0042H ;POKE 8088 MEMORY FUNCTION ; BIOS WRITE TYPES BWRNOR EQU 0 ;NORMAL WRITE BWRDIR EQU 1 ;WRITE TO A DIRECTORY SECTOR BRWUA1 EQU 2 ;WRITE TO 1ST SECTOR OF UNALLOC BLOCK ; FILE CONTROL BLOCK ORG 0 FCBDN RB 1 ;DISK NAME FCBFN RB 8 ;FILE NAME FCBFNL EQU 8 ;FILE NAME LENGTH FCBFT RB 3 ;FILE TYPE FCBFTL EQU 3 ;FILE TYPE LENGTH FCBRO EQU FCBFT+0 ;R/O FLAG FCBROF EQU 10000000B ; R/O FLAG VALUE FCBSYS EQU FCBFT+1 ;SYS FLAG FCBSYSF EQU 10000000B ; SYS FLAG VALUE FCBARC EQU FCBFT+2 ;ARCHIVE FLAG FCBARCF EQU 10000000B ; ARCHIVE FLAG VALUE FCBEX RB 1 ;EXTENT RB 1 FCBRWF RB 1 ;R/W FLAG FCBRWFF EQU 10000000B ; R/W FLAG VALUE FCBRC RB 1 ;RECORD COUNT FCBDM RB 16 ;DISK ALLOCATION MAP FCBNR RB 1 ;NEXT RECORD TO BE READ OR WRITTEN FCBLS EQU 33 ;FCB LENGTH FOR SEQUENTIAL I/O FCBRR RB 3 ;RANDOM RECORD POINTER FCBLR EQU 36 ;FCB LENGTH FOR RANDOM I/O ;** MISCELLANEOUS EQUATES ; BIOSREL EQU TPA+128 ;ORIGIN FOR RELOCATOR RELMODL EQU TPA+1 ;SLOT FOR LENGTH OF RELOCATABLE MODULE RELMOD EQU TPA+256 ;START OF RELOCATABLE MODULE PAGE ;*** MAIN PROGRAM ; ORG BIOSREL LXI SP,TPA ;INIT (SP) ; COMPUTE RELOCATION FACTOR LHLD BBIOS ;GET ADDR OF BIOS MEMORY AREA MOV A,H ;SAVE HIGH ORDER BYTE AS STA RELFCT ; THE RELOCATION FACTOR ; COPY RELOCATABLE BIOS TO BIOS MEMORY AREA XCHG ;(DE) = ADDR OF BIOS MEMORY AREA LHLD RELMODL ;GET RELOCATABLE MODULE LENGTH MOV B,H MOV C,L LXI H,RELMOD ;GET START OF RELOCATABLE MODULE COPY: MOV A,M ;DO COPY STAX D INX H INX D DCX B MOV A,B ORA C JNZ COPY ; DO RELOCATION LHLD RELMODL ;COMPUTE START OF RELOCATION TABLE MOV B,H ; (BC)=# OF BYTES IN MOV C,L ; RELOCATABLE MODULE LXI H,RELMOD DAD B XCHG ;(DE)=START OF RELOCATION TABLE LHLD BBIOS XCHG ;(DE)=START OF BIOS MEMORY AREA ;(HL)=RELOCATION TABLE POINTER RELOC1: PUSH H ;SAVE THE RELOCATION TABLE POINTER MOV H,M ;GET NEXT RELOCATION TABLE BYTE MVI L,8 ; WHICH CONTAINS RELOCATION FOR 8 ADDRS RELOC2: MOV A,H ;GET THE RELOCATION BYTE RAL ;ROTATE LEFT MOV H,A ;RESAVE IT JNC RELOC3 ;IF NO CARRY, THEN NO NEED TO ADJUST LDAX D ;GET BIOS BYTE ADI 0 ;ADJUST BYTE BY RELOCATION FACTOR RELFCT EQU $-1 STAX D ;REPLACE BIOS BYTE WITH UPDATED VALUE RELOC3: INX D ;POINT TO NEXT BIOS BYTE DCX B ;COUNT THIS BYTE AS DONE MOV A,B ;IS ENTIRE MODULE RELOCATED ORA C JZ DOCOLD ;BR IF DONE DCR L ;RELOCATION BYTE COUNTER JNZ RELOC2 ;BR IF MORE INFO IN THIS BYTE POP H ;RECAL POINTER TO RELOCATION TABLE INX H ;BUMP POINTER JMP RELOC1 ;CONTINUE RELOCATION ; DONE WITH RELOCATION. DO COLD BOOT. DOCOLD: LHLD BBIOS ;GET ADDR OF BIOS MEMORY AREA PCHL ;1ST INSTRUCTION THERE IS ; JUMP TO COLD BOOT IF ($-BIOSREL) GT 128 %: RELOCATOR IS TOO LARGE ENDIF END ;1ST INSTRUCTION THERE IS ; JUMP TO COLD BOOT IF ($-BIOSREL) GT 128 %: RELOC