home *** CD-ROM | disk | FTP | other *** search
- PAGEWIDTH 96
- TITLE 'CP/M-80 EMULATOR FOR CP/M-86'
- ; *** Z80.A86 *** VERSION 1.2 09/25/84
- ;
- ; WRITTEN BY PAT HESTER 08/12/83
- ; MODIFIED BY BILL EARNEST FOR CP/M-86
- ; LAST EDIT 9/25/84
- ; 09/25/84 ADD REL JMPS, REG EXCHGS FOR Z80
- ; 09/22/84 ADD INTERNAL REPARSE WHICH CPM-86 HASNT
- ; 09/18/84 CUT .CMD FILE SIZE FOR FASTER LOADING (WDE)
- ; 09/17/84 FLAG USAGE FIXED, MP/M FUNCTS REPLACED SO
- ; CAN BE RUN UNDER CP/M-86. WILL NOW RUN WM.COM OK (WDE)
- ;
- ; GENCMD Z80 EXTRA[MC00]
- ;
- ; INVOCATION:
- ; Z80 filename<.typ> (typ defaults to .COM)
- ;
- ; **** 8080 OP CODES ARE ALLOWED ***
- ; **** A FEW Z-80 INSTR. ARE SUPPORTED (NOT MANY) ****
- ; **** PROGRAMS MUST USE STRICT CP/M CALLS THRU 0 AND 5 ****
- ; **** THE BIOS JUMP TABLE MUST NOT BE ACCESSED ****
- ; **** EXCEPT FOR CONIN, CONOU, CONST, LIST ****
- ; **** NO GAME PLAYING WITHIN CP/M ****
- ;
- ; REGISTER USAGE:
- ; SI Z80 INSTRUCTION POINTER
- ;
- BDOS EQU 0E0H ;BDOS INTERRUPT VECTOR
- BDOS_LIST EQU 5 ;LIST OUTPUT
- BDOS_DIRECT EQU 6 ;DIRECT CONSOLE I/O
- BDOS_PRINT EQU 9 ;PRINT STRING
- BDOS_INPUT EQU 10 ;READ CONSOLE BUFFER
- BDOS_OPENF EQU 15 ;OPEN FILE
- BDOS_CLOSEF EQU 16 ;CLOSE FILE
- BDOS_READ_NEXT EQU 20 ;READ SEQUENTIAL
- BDOS_GET_DISK EQU 25 ;RETURN CURRENT DISK NUMBER
- BDOS_DMA_OFFSET EQU 26 ;SET DMA OFFSET
- BDOS_DMA_BASE EQU 51 ;SET DMA BASE
- BDOS_TERMINATE EQU 0 ;TERMINATE PROCESS
- ;BDOS_PARSE EQU 152 ;PARSE FILE NAME
- ;
- CR EQU 0DH ;CARRAIGE RETURN
- LF EQU 0AH ;LINE FEED
- BEL EQU 07H ;RING BELL
- ;
- ZJMP EQU 0C3H ;Z80 JUMP OP CODE
- ZJZ EQU 0CAH ;Z80 JUMP ON ZERO
- ZRET EQU 0C9H ;Z80 RETURN CODE
- ZCALL EQU 0CDH ;Z80 CALL OP CODE
- ZLDCNN EQU 0EH ;Z80 LD C,nn OP CODE
- ZLDENN EQU 01EH ;Z80 LD E,nn OP CODE
- ZLDEC EQU 059H ;Z80 LD E,C OP CODE
- ZORA EQU 0B7H ;Z80 ORA A CODE
-
- CSEG
- CALL INITIALIZE ;SET UP CP/M-80 AREAS, ETC
- CALL LOAD_Z80 ;LOAD Z80 PROGRAM INTO ESEG
- JC EXIT
- CALL RUN_Z80 ;EMULATION
- EXIT:
- MOV DX,OFFSET MSG_TERMINATE
- CALL PRINT
- MOV DL,0 ;RELEASE MEMORY
- MOV CL,BDOS_TERMINATE
- INT BDOS ;TERMINATE PROCESS
- ;
- INITIALIZE:
- PUSH ES
- MOV CL,BDOS_GET_DISK
- INT BDOS
- MOV Z80_DISK,AL ;Z80 CURRENT DISK
- POP ES
- MOV SI,OFFSET BIOSIMG
- MOV DI,OFFSET Z80_BIOSV
- MOV CX,OFFSET BIOIMGE-OFFSET BIOSIMG
- REP MOVSB ;SETUP BIOS VECTORS IN USER SPACE
- ;
- MOV SI,OFFSET TBUF+1
- MOV DI,OFFSET Z80_TAIL
- BNKLP: LODS AL
- OR AL,AL
- JZ HELP
- CMP AL,' '
- JE BNKLP
- EATLP: LODS AL
- OR AL,AL
- JZ INIDUN
- CMP AL,' '
- JNE EATLP
- MOV BL,-1
- DEC SI
- PUSH SI
- TAILLP: LODS AL
- STOS AL
- INC BL ;COUNT BYTE
- OR AL,AL ;TEST BYTE
- JNZ TAILLP
- MOV Z80_DMA,BL ;TAIL SIZE
- POP SI
- MOV DI,OFFSET Z80_FCB
- CALL GETFN
- MOV DI,OFFSET Z80_FCB+16
- CALL GETFN
- INIDUN: RET
- ;
- HELP:
- MOV DX,OFFSET HLP_MSG
- CALL PRINT1
- POP AX ;ADJUST STACK FOR INIT RETURN
- JMP EXIT
- ;
- GETFN:
- call nitf
- call gstart
- jnz ntblnk
- ret
- ntblnk: call getdrv
- call getps
- RET
- ;
- nitf: push di
- xor al,al
- stos al
- mov al,' '
- mov cx,11
- rep stos al
- xor al,al
- mov cx,4
- rep stos al
- pop di
- ret
- ;
- gstart: call getch
- jz isdelm
- dec si
- ret
- isdelm: cmp al,';'
- jne ntsemic
- ret
- ntsemic: or al,al
- jnz gstart
- ret
- ;
- getch: lods al
- cmp al,'.'
- jne t1
- ret
- t1: cmp al,','
- jne t2
- ret
- t2: cmp al,';'
- jne t2a
- ret
- t2a: cmp al,' '
- jne t3
- ret
- t3: cmp al,':'
- jne t4
- ret
- t4: cmp al,'='
- jne t5
- ret
- t5: cmp al,'<'
- jne t6
- ret
- t6: cmp al,'>'
- jne t7
- ret
- t7: or al,al
- ret
- ;
- getdrv:
- inc si
- lods al
- dec si
- dec si
- cmp al,':'
- jnz gdret
- lods al
- sub al,'@'
- stos al
- inc si
- ret
- gdret: inc di
- ret
- ;
- getps:
- mov cx,8
- call getnam
- cmp al,'.' ;dot terminator?
- jnz gtpret
- ftpont: cmp cl,0
- jz getft
- inc di
- dec cl
- jmps ftpont
- getft: mov cx,3
- call getnam
- gtpret: ret
- ;
- getnam: call getch
- jnz gnl1
- ret
- gnl1: cmp al,'*'
- jz ambig
- stos al
- dec cl
- jnz getnam
- jmps getdel
- ambig: mov al,'?'
- qfill: rep stos al
- getdel: call getch
- jnz getdel
- ret
- ;
- LOAD_Z80:
- PUSH ES
- mov al,fcbt1
- cmp al,' '
- jne typset
- mov fcbt1,'C'
- mov fcbt2,'MO'
- typset: MOV CL,BDOS_OPENF
- MOV DX,OFFSET FCB
- INT BDOS ;OPEN Z80 PROGRAM FILE
- INC AL ;0FFH=ERROR
- POP ES
- JZ LOAD_ERROR
- PUSH ES
- MOV CL,BDOS_DMA_BASE
- MOV DX,ES ;DMA BASE AT ESEG ORIGIN
- INT BDOS ;SET IT
- MOV DX,OFFSET Z80_TPA ;BEGIN LOAD THE FILE AT 0100H
- LOAD_LOOP:
- PUSH DX
- MOV CL,BDOS_DMA_OFFSET
- INT BDOS ;DMA NOW POINTS TO NEXT 128 BYTE BLOCK
- MOV CL,BDOS_READ_NEXT
- MOV DX,OFFSET FCB
- INT BDOS ;READ NEXT RECORD
- OR AL,AL ;0 INDICATES READ OK
- JNZ LOAD_EXIT ;END OF FILE
- POP DX
- ADD DX,128 ;POINT TO NEXT BLOCK
- JMP LOAD_LOOP
- LOAD_EXIT:
- POP DX ;RESTORE STACK
- MOV CL,BDOS_CLOSEF
- MOV DX,OFFSET FCB
- INT BDOS ;CLOSE IT UP
- MOV DX,OFFSET Z80_DMA ;SET DEFAULT DMA
- MOV CL,BDOS_DMA_OFFSET
- INT BDOS
- POP ES
- CLC ;RESET ERROR
- RET
- LOAD_ERROR:
- MOV DX,OFFSET MSG_NO_FILE
- CALL PRINT
- POP ES
- STC ;SET ERROR
- RET
-
- RUN_Z80:
- MOV SI,0100H ;INITIALIZE Z80 IP TO BASE OF TPA
- ; PUSHF
- RUN_LOOP:
- CMP SI,0C000H ;TOP OF Z80 MEMORY
- JNB Z80_RANGE_ERROR ;JUMP OUT OF RANGE
- CMP SI,0BFF8H ;BDOS CALL VECTOR
- JE Z80_BDOS_CALL
- Z80_OK:
- MOV DI,ES:[SI] ;DI[L] CONTAINS Z80 INSTRUCTION
- AND DI,00FFH ;REMOVE HIGH ORDER BYTE
- SAL DI,1 ;MULTIPLY BY 2 FOR JUMP OFFSET
- INC SI ;BUMP Z80 INSTRUCTION ADDRESS
- MOV BX,ES:[SI] ;WORD AFTER OP CODE
- MOV CX,JTABLE[DI] ;CX IS ADDRESS OF OP ROUTINE
- ; POPF
- ; PUSH ES
- ; LAHF
- SAHF
- CALL CX ;EXECUTE INSTRUCTION
- ; POP ES
- ; PUSHF
- LAHF
- JMP RUN_LOOP ;NEXT PLEASE
- Z80_BDOS_CALL:
- PUSH AX
- MOV CH,0
- MOV CL,Z_C
- MOV DX,Z_DE
- PUSH SI
- PUSH DS
- PUSH ES
- PUSH ES
- POP DS
- INT BDOS
- POP ES
- POP DS
- MOV Z_HL,BX
- MOV Z_A,AL
- MOV Z_DE,DX
- POP SI
- CALL Z80_RET
- POP AX
- JMP RUN_LOOP
- Z80_RANGE_ERROR:
- CMP SI,0FFFFH
- JE Z80_END ;BOOT
- PUSH ES
- MOV DX,OFFSET MSG_RANGE_ERROR
- CALL PRINT
- POP ES
- Z80_END:
- ; POPF
- RET
- ;
- JTABLE:
- NOLIST
- INCLUDE JUMPADDR.Z80 ;JUMP ADDRESS TABLE
- LIST
- EDTBL:
- NOLIST
- INCLUDE EDADDR.Z80
- LIST
- CBTBL:
- NOLIST
- INCLUDE CBADDR.Z80
- LIST
- ;
- INCLUDE CODE8086.Z80 ;8086 INSTS. FOR Z80 OP CODES
- INCLUDE CODECB.Z80
- INCLUDE CODEED.Z80
- PRINT:
- PUSH ES
- PUSH DX
- MOV DX,OFFSET MSG_Z80
- CALL PRINT1
- POP DX
- CALL PRINT1
- MOV DX,OFFSET MSG_CR_LF
- CALL PRINT1
- POP ES
- RET
- ;
- PRINT1: MOV CL,BDOS_PRINT
- INT BDOS
- RET
-
- DSEG
- ORG 05CH
- FCB:
- rb 9
- fcbt1 rb 1
- fcbt2 rw 1
- ORG 06CH
- FCB2:
- ORG 080H
- TBUF:
- ORG 0100H ;PAST UDA
- Z_REGISTERS: ;PRIMARY REGISTER SET
- Z_C RB 1 ;REGISTER C
- Z_B RB 1 ;REGISTER B
- Z_E RB 1 ;REGISTER E
- Z_D RB 1 ;REGISTER D
- Z_L RB 1 ;REGISTER L
- Z_H RB 1 ;REGISTER H
- Z_F RB 1 ;REGISTER F...Z80 CONTROL FLAGS
- Z_A RB 1 ;REGISTER A
- ORG 0100H
- Z_BC RW 1 ;REGISTER BC
- Z_DE RW 1 ;REGISTER DE
- Z_HL RW 1 ;REGISTER HL
- Z_AF RW 1 ;REGISTER AF
- Z_SP DW 0BFF0H ;Z80 STACK POINTER
- ;
- Z_ALTR RW 3
- Z_ALTA RW 1
- Z_X RW 1
- Z_Y RW 1
- Z_TEMP RW 3 ;SCRATCH FOR SWAP
-
- MSG_NO_FILE DB 'NO Z80 FILE$'
- MSG_TERMINATE DB 'EXITING TO CP/M-86$'
- MSG_RANGE_ERROR DB 'BRANCH OUTSIDE ADDRESS SPACE$'
- MSG_Z80_OP DB 'Z80 OP CODE DETECTED, ONLY 8080 ALLOWED$'
- MSG_Z80 DB CR,LF,'z80-->$'
- MSG_CR_LF DB CR,LF,'$'
- HLP_MSG DB 'Syntax: Z80 cmd <parameters>',cr,lf
- DB 'Where cmd is 8080 file (default .COM)',cr,lf
- DB 'and <parameters> are the normal arguments.',cr,lf,'$'
- ; START OF HI RAM IMAGE
- BIOSIMG:
- DB ZJMP
- DW 0FFFFH ;JP COLDBOOT
- DB ZJMP
- DW 0FFFFH ;JP WARMBOOT
- DB ZJMP
- DW OFFSET ZBIOS1 ;JP CONST
- DB ZJMP
- DW OFFSET ZBIOS2 ;JP CONIN
- DB ZJMP
- DW OFFSET ZBIOS3 ;JP CONOUT
- DB ZJMP
- DW OFFSET ZBIOS4 ;JP LIST
- DB ZJMP
- DW 0FFFEH ;JP PUNCH (NG)
- DB ZJMP
- DW 0FFFEH ;JP READER (NG)
- DB ZJMP
- DW 0FFFEH ;JP HOME (NG)
- DB ZJMP
- DW 0FFFEH ;JP SELDSK (NG)
- DB ZJMP
- DW 0FFFEH ;JP SETTRK (NG)
- DB ZJMP
- DW 0FFFEH ;JP SETSEC (NG)
- DB ZJMP
- DW 0FFFEH ;JP SETDMA (NG)
- DB ZJMP
- DW 0FFFEH ;JP READ (NG)
- DB ZJMP
- DW 0FFFEH ;JP WRITE (NG)
- DB ZJMP
- DW 0FFFEH ;JP LISTST (NG)
- DB ZJMP
- DW 0FFFEH ;JP SECTTRANS (NG)
- ;
- DB ZLDCNN,BDOS_DIRECT ;LD C,BDOS_DIRECT (RAW I/O)
- DB ZLDENN,0FEH ;LD E,BDOS_GET_STATUS
- DB ZCALL
- DW 0BFF8H ;JP BDOS
- DB ZRET
- ;
- DB ZLDCNN,BDOS_DIRECT ;LD C,BDOS_DIRECT (RAW I/O)
- DB ZLDENN,0FFH ;LD E,BDOS_INPUT_CHAR
- DB ZCALL
- DW 0BFF8H ;JP BDOS
- DB ZORA ; ORA A
- DB ZJZ
- DW OFFSET ZBIOS2
- DB ZRET
- ;
- DB ZLDEC ;LD E,C
- DB ZLDCNN,BDOS_DIRECT ;RAW I/O
- DB ZCALL
- DW 0BFF8H ;JP BDOS
- DB ZRET
- ;
- DB ZLDEC ;LD E,C
- DB ZLDCNN,BDOS_LIST ;LD C,OUTPUT
- DB ZCALL
- DW 0BFF8H ;JP BDOS
- DB ZRET
- ;
- RB 155
- DW 0FFFFH ;FORCE REBOOT
- RB 14
- BIOIMGE:
- ;
- ESEG
- Z80_BOOT DB 0C3H ;JP BOOT
- DW 0BF03H ;0FFFFH RETURNS TO 8086
- Z80_IOBYTE DB 0 ;IOBYTE
- Z80_DISK DB 0 ;CURRENT DISK
- Z80_BDOS DB 0C3H ;JMP BDOS
- DW 0BFF8H ;SET FOR 48K TPA
- ORG 05CH ;Z80 FCB
- Z80_FCB:
- DB 0,' ',' ',0,0,0,0 ;ONLY ONE VALID
- DB 0,' ',' ',0,0,0,0 ;NOT PARSED
- ORG 080H
- Z80_BUF:
- Z80_DMA DB 0
- Z80_TAIL:
-
- ORG 0100H ;BEGINNING OF Z80 TPA
- Z80_TPA:
- ORG 0BF00H ;BIOS JUMP TABLE
- Z80_BIOSV:
- RB 1
- RW 1
- RB 1
- RW 1
- RB 1
- RW 1
- RB 1
- RW 1
- RB 1
- RW 1
- RB 1
- RW 1
- RB 1
- RW 1
- RB 1
- RW 1
- RB 1
- RW 1
- RB 1
- RW 1
- RB 1
- RW 1
- RB 1
- RW 1
- RB 1
- RW 1
- RB 1
- RW 1
- RB 1
- RW 1
- RB 1
- RW 1
- RB 1
- RW 1
-
- ZBIOS1: ;GET CONSOLE STATUS
- RB 8
- ZBIOS2: ;GET ONE CHARACTER
- RB 12
- ZBIOS3: ;SEND ONE CHARACTER
- RB 7
- ZBIOS4: ;ONE CHAR TO LIST
- RB 7
- ;
- ORG 0BFF0H
- RW 1 ;
- ORG 0BFFFH
- RB 1 ;MAKE SURE MP/M-86 DOES
-
- END
-