home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols200
/
vol217
/
z80.a86
< prev
next >
Wrap
Text File
|
1986-02-12
|
9KB
|
533 lines
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