home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol040
/
host.z80
< prev
next >
Wrap
Text File
|
1984-04-29
|
9KB
|
448 lines
; HOST Program for AMD 96-4016 Z8000 Monitor
;
; Sourced March '80 by Trevor Marshall
; Elec Eng Dept
; Uni W.A.
;
; This program was written for a Z80 CPU
; running a CDOS 2.17 Disk Operating System.
;
; It has been modified for 8080 CPU
; but not fully tested with that CPU
;
; Most code is compatible with other CP/M
; systems, but will have to be tailored
; to the individual's hardware environment
;
; Although the AMD SYS 8/8 uses parallel
; ports for handshaking the 96-4016 will also
; support serial I/O and this method is
; usually preferable.
; The AMD Monitor uses an 8 bit data word with
; parity generated in software.
; If you cannot configure your HOST USART
; to that format then you must null the
; parity generation with NOPs and the parity
; checking may be defeated with a prior RET
; Note that the AMD SYS 8/8 appears to have a
; CP/M compatible operating system
;
BDOS: EQU 5 ;CDOS system call addr
RNEXT: EQU 14H ;Read next record
WNEXT: EQU 15H ;Write next record
FCREATE: EQU 16H ;Create a file
RESET: EQU 0DH ;Reset CDOS
FOPEN: EQU 0FH ;Open a file
FCLOSE: EQU 10H ;Close a file
DMA: EQU 1AH ;Set disk buffer address
FORMAT: EQU 86H ;Format name to FCB
NAK: EQU 15H ;CTL-U
ENQ: EQU 5 ;CTL-E
ACK: EQU 6 ;CTL-F
SOH EQU 1 ;CTL-A
STX: EQU 2 ;CTL-B
EOT: EQU 4 ;CTL-D
EOF: EQU 1AH ;End of file marker byte
;
;THE FOLLOWING EQUATES ARE HARDWARE DEPENDENT
;
CSTATP: EQU 0F7H ;Console driver status port
CDATA: EQU 0F6H ;Console data port
CRDA: EQU 2 ;RDA bit
CTBE: EQU 1 ;TBE bit
;
ORG 100H
;
START: LD SP,80H
LD A,0
LD (FLAG),A ;Clear the file opened flag
; Now output system prompt to console
LD DE,MSG
LD C,9 ;Print Buffered Line
CALL BDOS
;
MORE: LD SP,80H ;Reset Stack Pointer
LD A,0
LD (CODE),A ;Clear the error code
CALL DIALOG ;Wait for an instruction
LD A,(NEWCODE) ;2 locs to ease debugging
LD (CURCODE),A ;Save it
; Now decode the Function request type
CP A,4
JP Z,OPEN
CP A,5
JP Z,CLOSE
CP A,6
JP Z,CREATE
CP A,7
JP Z,READ
CP A,8
JP Z,WRITE
;
JP N7 ;If not one of the above instrs
;
; S/R to set up FCB name in FCB block from BFFR data
;
SETUP LD A,(REQBFFR) ;Fetch the drive (A - C)
SUB A,40H ;A = 01 IN FCB
LD (REQBFFR+1),A ;Put drive # in FCB
LD HL,REQBFFR+1 ;Point at start of legal code
LD DE,FCB ;Point at FCB area
LD BC,12 ;# of bytes in name & drive
; LDIR ;Shift name to FCB
; implement the LDIR in 8080 code:
L1: LD A,(HL) ;***** THIS CODE HAS NOT
LD (DE),A ; BEEN CHECKED******
INC HL
INC DE
DEC BC
LD A,C ;Is BC = 0
OR A,B
JP NZ,L1
;
RET
;
;Now try to open file
OPEN: LD C,RESET
CALL BDOS ;First log off all disks
CALL SETUP ;Set up FCB
LD DE,FCB
LD C,FOPEN
CALL BDOS ;Open file
; Any errors?
ADD A,1 ;Is a = -1 ?
JP Z,N7
; Opened successfully, now can process read or write
LD A,0FFH
LD (FLAG),A ;Set opened flag
CALL TRNS ;Acknowledge
JP MORE ;Get next instruction
;
WRITE: LD A,(FLAG) ;Check file is created or open
CP A,0
JP Z,N5 ;no, send error code 3
; Now set the DMA address to BFFR
LD C,DMA
LD DE,BFFR
CALL BDOS
;
LD DE,FCB
LD C,WNEXT
CALL BDOS ;Write the record
CP A,1 ;entry error
JP Z,N5 ; send code 3
CP A,2
JP Z,N7 ;Send code 1 if out of space
CP 0 ;OK
JP NZ,N8 ;Send code 2 for other errors
; Must be OK,wait for next instruction
CALL TRNS
JP MORE
;
CLOSE: LD A,(FLAG) ;Dont close an unopened file
CP 0
JP Z,N5 ;not open
LD C,FCLOSE
LD DE,FCB
CALL BDOS
CP A,0FFH
JP Z,N7 ;A=FF means not found
LD A,0
LD (FLAG),A ;Clear the open file flag
LD (CODE),A ;Clr error flag
JP N10
N7: LD A,1 ;Send error code 1
JP N6
N8: LD A,2 ;Send error code 2
JP N6
N5: LD A,3 ;Send error code 3
N6: LD (CODE),A ;File not open or created
N10: CALL TRNS
; Omit the following for 8080 CP/M
; LD C,96H ;Call to CDOS 2.17 to turn
; CALL BDOS ; drive motors off
JP MORE
;
READ: LD A,(FLAG) ;Is file open ?
CP 0
JP NZ,N2 ;Yes
LD C,RESET ;No,open it
CALL BDOS
CALL SETUP
LD DE,FCB
LD C,FOPEN
CALL BDOS
ADD A,1
JP Z,N5 ;type 3 error, not found
LD A,0FFH
LD (FLAG),A ;Set open flag
; File opened now read record
N2: LD C,DMA ;set CDOS DMA addr to bffr
LD DE,BFFR
CALL BDOS
LD C,RNEXT ;read next record
LD DE,FCB
CALL BDOS
; Now process error codes
CP 0 ;1 = <EOF>
JP Z,M1
; Must be 1, End Of File
; Note that this error is only returned AFTER an
; abortive attempt to fetch the next sector, and
; <EOF> within data is transferred normally, so
; ASM will give errors unless a QUIT instruction
; is used to end the source file.
LD A,1
LD (CODE),A
CALL TRNS ;Dont send any data
JP MORE
M1: CALL SEND ;Transmit normal data
JP MORE
;
CREATE: LD A,(FLAG) ;Is file open?
CP 0
JP NZ,N5 ;Yes send error code 3
LD C,RESET ;Log off all disks
CALL BDOS ;Prior to directory operations
CALL SETUP
; First check if a file already exists with this name
; Dont delete it,as it may be a mistaken command
LD DE,FCB
LD C,11H ;Search Directory cmd
CALL BDOS
CP A,0FFH
JP Z,MI3 ;Entry was not found
LD A,(HL) ;Fetch the first directory byte
CP A,0E5H ;Is it erased
JP NZ,N5 ;No, send error
MI3: LD C,FCREATE
LD DE,FCB
CALL BDOS
CP A,0FFH
JP Z,N7 ;Send error code 1
CALL TRNS
LD A,0FFH
LD (FLAG),A ;Set the open flag
JP MORE
;
;
; S/R to accomplish I/O
; N.B. THESE WILL BE HARDWARE DEPENDENT
CSTAT: IN A,CSTATP
AND CRDA
RET Z
LD A,-1
RET
;
CHIN: CALL CSTAT
JP Z,CHIN
IN A,CDATA
AND 7FH ;Strip off parity bit
RET
;
CRDY: IN A,CSTATP
AND CTBE
RET Z
LD A,-1
RET
;
COUT: PUSH AF
C1: CALL CRDY
JP Z,C1
POP AF
OUT CDATA,A
RET
;
;
; S/R DIALOG to talk to Z8000
DIALOG: LD HL,0FFFFH ;Load a delay value to HL
; We will decrement HL until 0, then switch the
; disk drive motors off
DI1: CALL CSTAT
JP NZ,DIA2 ;Have input,exit motor loop
DEC HL
LD A,L ;No flag setting after DEC HL
OR H
JP NZ,DI1 ;Try the loop again
; Have now waited long enough, assume Z8000 done
; LD C,96H ;Call to CDOS 2.17 to turn
; CALL BDOS ; drive motors off
JP DIA2
KNACK: LD A,NAK
CALL COUT
JP DIALOG ;Service motors
DIA2: CALL CHIN
CP ENQ
JP NZ,KNACK ;Only <ENQ> is valid
ACKNL: LD A,ACK
CALL COUT
RECVE: LD HL,REQBFFR
CALL CHIN
CP SOH ;Answer should be <SOH>
JP NZ,FLUSH
CALL CHIN ;FUNCTION REQUEST CODE
SUB A,30H
LD (NEWCODE),A
; We will just receive chars and store them in req bffr
RECVA: CALL CHIN
CP A,EOT
JP Z,RECVB ;Message ends with <EOT>
CP A,STX
JP Z,RECVA ;Discard it
; Now process two hex bytes
SUB 30H ;Pseudo-Hex format is used
; Cabt SLA C in 8080, so rewrite
SCF
CCF
RLA
SCF
CCF
RLA
SCF
CCF
RLA
SCF
CCF
RLA
LD C,A ;Save first hex digit
CALL CHIN
; SLA C
; SLA C
; SLA C
; SLA C
SUB A,30H
AND A,0FH ;Mask off upper nibble
ADD A,C ;Now have Hex digit
LD (HL),A
INC HL
LD A,L
CP REQBUFFEND AND 0FFH
JP NZ,RECVA
LD A,H
CP REQBUFFEND SHR 8
JP NZ,RECVA
LD HL,BFFR ;Now point at data buffer
JP RECVA
;
RECVB: LD A,ACK
CALL COUT
RET
;
;FLUSH routine to discard all input characters
; up to the next <EOT> after an input error
;
FLUSHB: LD A,NAK
CALL COUT ;Send a <NAK>
FLUSH: CALL CHIN
CP EOT ;EOT means end of input
JP NZ,FLUSHB ;Continue to flush
JP DIALOG ;Try to fetch the data again
;
; S/R to transmit code,response & data in 96-4016 format
;
SEND: LD A,ENQ
CALL COUT ;Ask permission to send
SENDA: CALL CHIN
CP A,ACK ;Must reply with <ACK>
JP NZ,SEND
SENDB: LD A,SOH
CALL COUT
LD A,(CURCODE)
ADD A,30H
CALL COUT ;Transmit the Function Code
LD A,STX
CALL COUT
LD A,'0' ;Error codes, first is zero
CALL COUT
LD A,(CODE) ;Second code byte
ADD '0'
CALL COUT
; Now transmit text
LD HL,BFFR
LP4: LD A,(HL)
LD C,A ;Save it
AND A,0F0H
; Cant SRA A in 8080,
; SRA A
; SRA A
; SRA A
; SRA A
SCF
CCF
RRA
SCF
CCF
RRA
SCF
CCF
RRA
SCF
CCF
RRA
ADD A,'0' ;Get in Pseudo-Hex
CALL COUT
LD A,C
AND A,0FH
ADD '0'
CALL COUT
INC HL
LD A,L
CP [BUFFEND AND 0FFH]
JP NZ,LP4
LD A,H ;L was equal,test H
CP A,[BUFFEND SHR 8]
JP NZ,LP4
;Now have finished buffer
J4: LD A,EOT
CALL COUT
; Now wait for <ACK>
CALL CHIN
CP ACK
RET Z
JP SEND
;
;
; S/R to transmit code and response only to 96-4016
;
TRNS: LD A,ENQ
CALL COUT ;Ask permission to send
TRNSA: CALL CHIN
CP A,ACK ;Must reply with <ACK>
JP NZ,TRNS
TRNSB: LD A,SOH
CALL COUT
LD A,(CURCODE)
ADD A,30H
CALL COUT ;Transmit the Function Code
LD A,STX
CALL COUT
LD A,'0' ;Error codes, first is zero
CALL COUT
LD A,(CODE) ;Second code byte
ADD '0'
CALL COUT
LD A,EOT
CALL COUT
; Now wait for <ACK>
CALL CHIN
CP ACK
RET Z
JP TRNS
;
MSG: DB 0DH,0AH,'Z8000 HOST Communication Program'
DB ' between CDOS and AMD 96-4016',0DH,0AH
DB 0DH,0AH,' '
DB 'Contact Trevor Marshall for operating'
DB ' proceedures.',0DH,0AH,'$'
REQBFFR DS 13
REQBUFFEND EQU $
BFFR: DS 128
BUFFEND EQU $
CURCODE DS 1 ;Current operation code
NEWCODE DS 1 ;New operation code
FCB: DS 33 ;FCB area
CODE DS 1 ;Operation status code
FLAG DS 1 ;0 means file is NOT OPEN
NOP
END START