#TITLE "8080 EMULATOR FOR NEC V-30 BY ESKAY 12/07/85" #PAGE 132,66 MODULE "EmulV30" ; ; This copyrighted program has been released to the Public Domain ; for NONCOMMERCIAL uses only. Users wishing to use this utility ; for ANY purpose other than personal use must first obtain written ; authorization. Commercial distribution of this utility is ; strictly forbidden without authorization and a $20.00 royalty fee ; per distributed copy. ; The above does not apply to distribution via "SIG-M library"! ; ; The author assumes no liability of any kind for damages arising ; from the use or inability to use this utility. ; JMP == 0XC3 ; ; below we define the CP/M version number which is returned in response to ; BDOS function 12. Note that TurboDOS and MP/M-86 users should select ; "0X0130" to recognize MP/M functions. See .DOC file for more info. ; CPMVER == 0X0022 ; CP/M VERSION RETURNED ; ; below, the new BDOS interrupt vector is defined ; BDOSN == 0XFE ; NEW BDOS INTERRUPT FOR EMULATION MODE ; LOC Extra# ; ; THIS BECOMES THE 8080 ENVIRONMENT ; SAVE A FEW BYTES BY STATIC ALLOCATION RATHER ; THAN DYNAMIC. ; ENV80: RES 0X7FFF RES 0X7FFF ; LOC Data# ; ; IN THIS VERSION OF EMUL, THE 8080 ENVIRONMENT IS ; CARRIED IN THE DATA SEGMENT AND LOADED INTO ALLOCATED ; RAM IN A 2-STEP PROCESS. NOTE THAT DATA SEGMENT BECOMES ; USABLE ONLY FROM 100H, THUS ALL EQUATES IN THE BDOS/BIOS ; AREA ARE SEEMINGLY OFF BY 0X100. ; WBOOT: BYTE JMP ; BASE PAGE WARMBOOT JUMP WORD &WBOOTE BYTE 0 BYTE 0 BDOS: BYTE JMP ; BDOS ENTRY POINT WORD &BDOSE LOC WBOOT+0X5C DFCB1: BYTE 0," ",0,0,0,0 ; DEFAULT FCB 1 DFCB2: BYTE 0," ",0,0,0,0 ; DEFAULT FCB 2 LOC WBOOT+0X80 DBUF: BYTE 0 ; DEFAULT DMA BUFFER RES 127 TPA: BYTE 0X11 ; LXI D,TEST1 WORD &TEST1-0X100 BYTE 0X0E,0X09 ; MVI C,9 BYTE 0XCD ; CALL BDOS WORD &BDOS-0X100 BYTE JMP ; JMP WBOOT WORD &WBOOT-0X100 TEST1: BYTE "ERROR: no command line specified.\r\n\7" BYTE "USAGE:\r\n" BYTE "EMUL [tail]\r\n" BYTE "Where is an 8080 CP/M .COM file which must be\r\n" BYTE "currently accessible, and [tail] is an optional command\r\n" BYTE "tail which is to be passed to the command file.\r\n" BYTE " This message is produced by the emulation mode.\r\n\n" BYTE "NOTE: commercial distribution without authorization\r\n" BYTE "strictly prohibited. License fee for commercial use: 20.00" BYTE " dollars.\r\n" BYTE "(c) 1985, S. Kluger, 7120 Skillman #2104," BYTE " Dallas TX 75231\r\n\n" BYTE "CP/M-80 available TPA space = 0100..FEFC (65020 bytes)." BYTE "\r\n$" ; BEGENV == . ; BEGINNING OF BDOS/BIOS ENVIRONMENT BDOSE == WBOOT+0XFDFD BYTE JMP WORD &NATIVE ; ; SIMULATED BIOS TABLE ; CBOOT == BDOSE+3 BYTE JMP ; COLD BOOT WORD &ENDEM WBOOTE == BDOSE+6 BYTE JMP ; WARMBOOT ENTRY (RETURN TO 16 BIT) WORD &ENDEM CONST == BDOSE+9 BYTE JMP ; CON STATUS WORD &BCONST CONIN == BDOSE+12 BYTE JMP ; CON IN WORD &BCONIN CONOT == BDOSE+15 BYTE JMP ; CON OUT WORD &BCONOT LIST == BDOSE+18 BYTE JMP ; LST OUT WORD &BLIST BYTE JMP ; REST IS INVALID WORD &INVAL BYTE JMP ; REST IS INVALID WORD &INVAL BYTE JMP ; REST IS INVALID WORD &INVAL BYTE JMP ; REST IS INVALID WORD &INVAL BYTE JMP ; REST IS INVALID WORD &INVAL BYTE JMP ; REST IS INVALID WORD &INVAL BYTE JMP ; REST IS INVALID WORD &INVAL BYTE JMP ; REST IS INVALID WORD &INVAL BYTE JMP ; REST IS INVALID WORD &INVAL BYTE JMP ; LIST STATUS WORD &BLSTS BYTE JMP ; REST IS INVALID WORD &INVAL BYTE JMP ; REST IS INVALID WORD &INVAL BYTE JMP ; REST IS INVALID WORD &INVAL ; RES 7 ; LEAVE SOME ROOM ; BCONST == CBOOT+0X40 BYTE 0X0E,0X0B,JMP WORD &NATIVE BCONIN == CBOOT+0X45 BYTE 0X0E,3,JMP WORD &NATIVE BCONOT == CBOOT+0X4A BYTE 0X59,0X0E,4,JMP WORD &NATIVE BLIST == CBOOT+0X50 BYTE 0X59,0X0E,5,JMP WORD &NATIVE BLSTS == CBOOT+0X56 BYTE 0XAF,0XC9 ; XRA A ! RET BYTE 0 ; NOP ; ; ENTER HERE WHEN GETTING CONTROL FROM ABOVE ; ENTRY == CBOOT+0X59 BYTE 0X31 WORD &STK80 BYTE 0X21,0,0 ; LXI H,0 BYTE 0XE5 ; PUSH H BYTE 0XC3,0,1 ; JMP 100H ; ; CALL THE HIGHER BEING IN THE V30 ; NATIVE == CBOOT+0X63 BYTE 0X79 ; MOV A,C ; GET FUNCTION # BYTE 0XFE,0X0C ; CPI 12 ; SEE IF VERSION CALL BYTE 0XC2 ; JNZ NO12 ; NO, SKIP WORD &NO12 BYTE 0X21 ; LXI H,CPMVER ; SET UP OUR VERSION CV == CBOOT+0X6A WORD CPMVER BYTE 0XC9 ; RET NO12 == CBOOT+0X6D BYTE 0XED,0XED,BDOSN ; CALL NATIVE (INT BDOSN) BYTE 0XC9 ; RET ; ; GO BACK TO CREATOR ; ENDEM == CBOOT+0X71 BYTE 0XED,0XFD ; RETURN FROM EMULATION ; ; INVALID BIOS CALL ; INVAL == CBOOT+0X73 BYTE 0X11 ; LXI D,ERRMSG WORD &ERRMSG BYTE 0X0E,0X09 ; MVI C,9 BYTE 0XCD ; CALL NO12 (BDOS) WORD &NO12 BYTE JMP ; JMP ENDEM (QUIT) WORD &ENDEM ; ERRMSG == CBOOT+0X7E BYTE "\r\n\nBIOS CALL NOT SUPPORTED!\r\n\n\7$" ; STK80 == WBOOT+0XFEF0 ; ENDENV == . ; END OF ENVIRONMENT ; LOC Data# ; ; +--------------------------------------------------+ ; | THIS IS THE EMULATOR CONTROL PROGRAM'S DATA AREA | ; +--------------------------------------------------+ ; BANNER: BYTE "\r\n---------------------------------------------" BYTE "\r\nEMUL Version 2.20 12/07/85" BYTE "\r\nCP/M-80 emulator for CP/M-86 and NEC V30 CPU" BYTE "\r\nCopyright 1985 S. Kluger. All Rights Reserved" BYTE "\r\n---------------------------------------------\r\n\n$" ; BADCPU: BYTE "\r\nNOT V20 OR V30 CPU???\r\n$" NOFIL: BYTE "ERROR: $" NOFIL1: BYTE " NOT FOUND!\r\n\7$" EMDONE: BYTE "\r\nEMUL: end of emulation\r\n$" ; DMABAS: WORD 0 ; ENTRY DMA BASE DMAOFF: WORD 0 ; ENTRY DMA OFFSET ; RES 0X100 STACK == . ; ; +----------------------------------------------------+ ; | THIS IS THE CONTROL PROGRAM. LOAD PROGRAM, PROCESS | ; | COMMAND LINE AND THEN SEND CONTROL TO WORLD BELOW. | ; +----------------------------------------------------+ ; LOC Code# ; START: MOV AX,DS ; GET DATA SEGMENT MOV SS,AX ; SET UP STACK MOV SP,&STACK CS MOV NTRYDS,AX ; SAVE ENTRY DS IN KNOWN LOCATION MOV CL,=52 ; GET DMA ADDRESS PUSH ES ; PRESERVE 8080 PAGE CALL IBDOS MOV DMABAS,ES MOV DMAOFF,BX POP ES MOV DX,&BANNER ; SAY WHO WE ARE MOV CL,=9 CALL IBDOS ; ; MAKE SOME TESTS (CHECK IF THIS IS V20 OR V30) ; MOV CL,=0X21 MOV AX,=2 SHR AX,CL TEST AX,=1 ; NONZERO MEANS 80186/188 JZ __MYB ; SKIP IF "MAYBE" __CBAD: MOV DX,&BADCPU JMP ERROR ; __MYB: XOR AL,AL MOV AH,=0X99 BYTE 0X0F,0X28,0XC4 ; NEC INSTRUCTION "ROL4 AH" OR AL,AL ; MUST HAVE CHANGED JZ __CBAD ; NOT V20/30 ; ; PREPARE 8080 ENVIRONMENT ; MOV CX,=0X8000 ; FIRST CLEAR RAM MOV DI,=0 XOR AX,AX REP STOS WORD MOV SI,&WBOOT ; MOVE BASE PAGE PLUS DEFAULT PGM MOV DI,=0 MOV CX,=(BEGENV-WBOOT) REP MOVS BYTE MOV SI,&BEGENV ; MOVE BDOS/BIOS AREA MOV DI,&BDOSE MOV CX,=(ENDENV-BEGENV) REP MOVS BYTE ; ; NOW LOAD THE PROGRAM ; MOV CX,=0X7F ; MOVE COMMAND LINE MOV SI,=0X80 MOV DI,SI REP MOVS BYTE CMP 0X5D,=BYTE ' ' ; EMPTY FILENAME? JNZ __V JMP SETDMA ; YES, GO RUN DEFAULT PROGRAM ; __V: MOV 0X5C+9,=WORD 0X4F43 ; MAKE ".COM" MOV 0X5C+11,=BYTE 'M' MOV DX,&0X5C ; POINT TO FILENAME MOV CL,=15 ; OPEN FILE CALL IBDOS INC AL JNZ OO MOV DX,&NOFIL MOV CL,=9 CALL IBDOS MOV SI,=0X5C ; POINT TO FCB MOV AL,[SI] INC SI OR AL,AL JZ __NDV ADD AL,=0X40 CALL PUTCH MOV AL,=':' CALL PUTCH __NDV: MOV CX,=11 __DFN: MOV AL,[SI] INC SI PUSHA CALL PUTCH POPA LOOP __DFN MOV DX,&NOFIL1 ERROR: MOV CL,=9 CALL IBDOS MOV CL,=0 JMP IBDOS ; OO: MOV DI,=0X100 __RL: MOV SI,=0X80 MOV CL,=20 ; READ A BLOCK MOV DX,=0X5C CALL IBDOS OR AL,AL JNZ LOADED MOV CX,=64 REP MOVS WORD JMPS __RL ; LOADED: MOV CL,=16 ; CLOSE THE FILE MOV DX,=0X5C CALL IBDOS ; ; SET UP FCBS ; MOV AX,ES MOV DS,AX MOV CX,=0X10 MOV SI,&DFCB2-0X100 MOV DI,&DFCB1-0X100 REP MOVS BYTE MOV BX,&DFCB2-0X100 MOV [BX],=BYTE 0 MOV CX,=11 __F: INC BX MOV [BX],=BYTE ' ' LOOP __F MOV BX,&DBUF-0X100 MOV CL,[BX] INC CL MOV CH,=0 PUSH CX MOV SI,&DBUF+2-0X100 MOV DI,&DBUF+1-0X100 __CLL: CMP CL,=0 JZ BLCL DEC CL CMP [SI],=BYTE ' ' JZ __FB INC SI JMPS __CLL ; __FB: DEC CL MOV [BX],CL REP MOVS BYTE POP CX __ZL: MOV [DI],=BYTE 0 INC DI CMP DI,=0X100 JZ __ZZ LOOP __ZL __ZZ: MOV SI,=0X81 ; SOURCE POINTER MOV DI,=0X5C ; DESTINATION POINTER CALL PFN ; PARSE FN JC SETDMA ; SKIP IF END OF LINE MOV DI,=0X6C ; NEXT DESTINATION POINTER CALL PFN JMPS SETDMA ; BLCL: MOV [BX],=BYTE 0 ; ; NOW SET UP DMA BUFFER ; SETDMA: MOV CL,=51 ; SET DMA BASE (OFFSET STILL 0X80) MOV DX,ES CALL IBDOS ; ; SET UP INTERRUPT VECTOR AND EXECUTE ; XOR AX,AX MOV DS,AX MOV 0X3FC,=WORD ENTRY MOV 0X3FE,ES MOV BDOSN*4,=WORD BDOSI MOV BDOSN*4+2,CS PUSH ES ; GET THE 8080 SEGMENT POP DS ; PUT INTO DATA SEG ; BYTE 0X0F,0XFF,0XFF ; BRKEM 0XFF ; CS MOV AX,NTRYDS ; ENT ENTRY DATA SEGMENT BACK MOV DS,AX MOV CL,=51 ; RESET DMA BASE MOV DX,DMABAS CALL IBDOS MOV CL,=9 MOV DX,&EMDONE CALL IBDOS MOV CL,=0 ; EXIT ; ; INTERNAL BDOS ENTRY POINT, SAVE ES ; IBDOS: PUSH ES INT 0XE0 POP ES RET ; ; OUTPUT A CHARACTER (USED FOR FILENAME DISPLAY) ; PUTCH: MOV CL,=2 MOV DL,AL JMPS IBDOS ; ; FILE NAME PARSER ; IN: SI=SOURCE (NULL TERMINATED), DI=DESTINATION ; OUT: SI=POINTER TO NEXT NON-DELIMITER ; IF CARRY SET, THEN END OF LINE ; PFN: CALL SKNB ; SKIP TO NONBLANK CMP 1[SI],=BYTE ':' ; DRIVE? JNZ __NDR ; NO, SKIP MOV AL,[SI] SUB AL,=0X40 ; MAKE 1..16 CMP AL,=16 JA __EOL MOV [DI],AL INC SI INC SI __NDR: INC DI ; POINT TO FILENAME PART MOV CL,=0 __LP: MOV AL,[SI] ; GET BYTE CMP AL,=' ' ; CHECK DELIM JZ __DL CMP AL,=0X5C JZ __DL CMP AL,=';' JZ __DL CMP AL,=0 ; EOL? JZ __EOL CMP AL,='.' JZ __PER CMP CL,=12 JZ __SKP MOV [DI],AL __SKP: INC CL INC DI __SKP1: INC SI JMPS __LP ; __DL: INC DI RET ; __PER: CMP CL,=8 JNZ __N8 JMPS __SKP1 ; __N8: INC DI INC CL JMPS __PER ; __EOL: STC RET ; SKNB: MOV AL,[SI] CMP AL,=' ' JZ __ISB CMP AL,=':' JZ __ISB CMP AL,=';' JZ __ISB CMP AL,=0X5C JZ __ISB CMP AL,='=' JNZ __NB __ISB: INC SI JMPS SKNB ; __NB: RET ; NTRYDS: WORD 0 ; ENTRY DATA SEGMENT ; ; EMULATOR BDOS INTERRUPT ; BDOSI: PUSH BP ; SAVE EMULATOR STACK CALL IBDOS POP BP IRET END  IF CARRY SET, THEN END OF LINE ; PFN: CALL SKNB ; SKIP TO NONBLA .