home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
sigm
/
vol157
/
ataribus.lbr
/
ATARIFN.CQM
/
ATARIFN.CSM
Wrap
Text File
|
1985-03-13
|
10KB
|
481 lines
title 'ATARIFN: ATARI-CPM interface "C" functions'
;************************************************
; ATARIFN.CSM - 9/17/83
; Provides BDS "C" functions to interface to
; the ATARI over the S100 interface board.
;
;GENERIC, EASILY PATCHABLE VERSION FOR BDS C V1.5
;
; Functions ending with '$' are internal functions
;dealing with the I/O ports directly which must be
;patched for different systems.
;
;************************************************
include <BDS.LIB>
include "ATARI.LIB"
function atarifnver
;************************************************
; char *atarifnver()
; Returns address of ATARIFN version string
; SHOULD BE UPDATED WHENEVER THIS FILE IS ALTERED
;
lxi h,ver
ret
ver: db '9/17/83'
db 0
endfunc
function ainit
;************************************************
; ainit ()
; Initializes ATARI-S100 interface ports.
; Must be called at least once.
; No results
; $$$ must be patched $$$
;
xra a ;reset 2661
out acmd
mvi a,4Eh ;1 stop bit, no parity, 8 bits
out amode
mvi a,7Eh ;16X clock, 19,200 baud (ok Bob??)
out amode
mvi a,15h ;reset flags, enable xmit & rcv
out acmd
in adata ;clean any junk
ret
ds 20 ;*extra space*
endfunc
function getcf
external cmdf$,inch$,gotch$
;************************************************
; int getcf (buf)
; char *buf
; Waits for next valid command frame on ATARIBUS
; and returns it in "buf". If key is pressed on
; console then will abort and return -1 else
; returns 0. Does not input console char.
;
; *NOTE*: DOES DIRECT CALL TO CPM BIOS CONSOLE
; STATUS ROUTINE, MUST BE CHANGED IF RUN IN A
; NON-CPM SYSTEM.
;
call ma1toh ;get buffer addr
shld buf ;save
push b ;save stack frame
lda base+2h ;$$$ get bios page
sta csts+2 ;$$$ to our vector
cflp:
;first wait for CMD- line to be false
wlo: lxi d,1200 ;timeout count (aprx 20msec @ 4mhz)
wlolp: call cmdf$ ;line drop yet?
jz drop ;yep..go drop junk chars
dcx d ;timeout?
mov a,d
ora e
jnz wlolp ;nope
;timeout, check for key pressed abort
call csts
jz wlo ;no key, keep waiting
;key pressed, abort with error
abort: lxi h,-1 ;return value
pop b ;stack frame
ret
;CMD- line is false, clean out junk chars from serial port
drop: call inch$
call inch$
;now wait for CMD- line to go TRUE
whi: lxi d,1200 ;timeout count (aprx 20msec @ 4mhz)
whilp: call cmdf$ ;start of command frame?
jnz getdf ;yep
dcx d ;timeout?
mov a,d
ora e
jnz whilp ;nope
;timeout, check for key pressed abort
call csts
jz whi ;no key, keep waiting
jmp abort ;key pressed, return error
;now get command frame data to buffer with checksum
getdf: lhld buf ;buffer adr
lxi b,0400h ;B=length, C=checksum
cmdlp: call inch ;get next char
mov m,a ;stuff in buffer
inx h
add c ;update checksum
aci 0 ;include carry
mov c,a
dcr b
jnz cmdlp ;get 4 chars
;now get checksum
call inch ;checksum to A
cmp c ;match?
jnz cflp ;no..ignore the frame
;valid command frame, wait for CMD- line to drop
lxi d,1200 ;timeout count (aprx 20msec @ 4mhz)
wdrop: call cmdf$ ;line drop yet?
jnz dropto ;no
;return 0 to caller
lxi h,0
pop b
ret
;check for timeout
dropto: dcx d ;timeout?
mov a,d
ora e
jnz wdrop ;nope
jmp cflp ;oops, timeout..drop command
;local sub
;>>>>> wait for next char. If char not received within around
; 50 msec then wait for CMD- line to drop and restart command
; wait loop.
inch: lxi d,3000 ;timeout count, (@ 4mhz)
inchlp: call gotch$ ;char received?
jnz inch$ ;yep..return char in A
dcx d ;timeout yet?
mov a,d
ora e
jnz inchlp ;nope
;timeout, restart the whole process
pop d ;drop return
jmp cflp
; vector to BIOS console status routine
csts: call 0006h ;BIOS console status
ora a ;set flags
ret
;
buf: ds 2 ;buffer addr
endfunc
function getdf
external gotch$,inch$,outrdy$,outch$
;************************************************
; int getdf (buf,len)
; char *buf
; int len
; Receives data frame of length "len" from
; ATARIBUS and places it in "buf" which should
; be at least "len" chars long. If the data frame
; is valid (checksum ok, no timeout) then sends ACK
; to ATARI and returns 0, else sends NAK to ATARI
; and returns -1.
;
call ma1toh ;buffer address
push h ;save
call ma3toh ;frame length
pop d ;buf adr again
push b ;save stack frame
xra a ;checksum & carry = 0
sta cksum
; loop to get data frame
dflp: call gch ;get char
stax d ;into buffer
inx d
mov c,a ;update checksum
lda cksum
add c
aci 0
sta cksum
dcx h ;all done?
mov a,h
ora l
jnz dflp ;not yet waldo
; got the data frame, get and check the checksum
cksmlp: call gch ;get checksum
mov c,a
lda cksum ;get ours
cmp c ;match?
jnz err ;no..THEY goofed (of course)
; good frame and good checksum, return honky dorey
mvi c,ACK ;char to send
lxi h,0 ;return value
; delay a bit then send char in C to ATARI
; and return value in HL to caller
return: mvi b,0 ;delay at least 850 us
rlp: nop
nop
nop
dcr b
jnz rlp
; send char in C to ATARI
sendlp: call outrdy$ ;ok to send?
jz sendlp ;not yet
mov a,c ;sho'nuf
call outch$
pop b ;stack frame
ret
;local sub
;>>>>> get next char from bus, return to main pgm with error if
; get a timeout (max wait around 50 msec)
gch: lxi b,3000 ;timeout count (@ 4mhz)
gchlp: call gotch$ ;get char?
jnz inch$ ;yep..return char in A
dcx b
mov a,b
ora c
jnz gchlp ;no timeout
;>>>>> timeout, drop return address, send NAK and return error
pop b
err: mvi c,NAK ;send NAK
lxi h,-1 ;return value
jmp return
cksum: ds 1 ;checksum byte
endfunc
function putdf
external outch$,outrdy$
;************************************************
; putdf (buf,len)
; char *buf
; int len
; Sends data frame to ATARI "len" chars long
; starting at address "buf". No results.
;
call ma1toh ;buffer address
push h ;save
call ma3toh ;frame length
pop d ;buf addr again
push b ;save stack frame
mvi b,0 ;checksum = 0
; loop to send data frame
dflp: call outrdy$ ;ok to send?
jz dflp ;nope
ldax d ;get buffer char
inx d
call outch$ ;send it
add b ;update checksum
aci 0 ;include carry
mov b,a
dcx h ;all done?
mov a,l
ora h
jnz dflp ;not yet clone
; send the checksum
cklp: call outrdy$ ;ok to send?
jz cklp ;alas..no
mov a,b
call outch$
pop b ;stack frame
ret
endfunc
function agetch
external gotch$,inch$
;************************************************
; int agetch ()
; Returns next char from ATARIBUS or -1 if
; timed out
;
lxi d,0 ;timeout count
getlp: call gotch$ ;char there?
jnz gotch ;yep
dcx d
mov a,d
ora e
jnz getlp ;no timeout
; timed out, return -1
lxi h,-1
ret
; got the char, return it
gotch: call inch$ ;get char
mov l,a
mvi h,0 ;return in HL
ret
endfunc
function aputch
external outrdy$,outch$
;************************************************
; aputch (c)
; char c
; Outputs character in "c" to ATARIBUS.
; No result
;
putlp: call outrdy$ ;ok to send?
jz putlp ;nope
call ma1toh ;get char
call outch$
ret
endfunc
function aputack
external outrdy$,outch$
;************************************************
; aputack ()
;Output an ACK character to ATARIBUS.
; No result
;
putlp: call outrdy$ ;ok to send?
jz putlp ;uh uh
mvi a,ACK ;send the ack
call outch$
ret
endfunc
function aputcmpl
external outrdy$,outch$
;************************************************
; aputcmpl ()
; Output an OPERATION COMPLETE character to ATARIBUS.
; No result
;
putlp: call outrdy$ ;ok to send?
jz putlp ;uh uh
mvi a,CMPL ;send the complete
call outch$
ret
endfunc
function aputerr
external outrdy$,outch$
;************************************************
; aputerr ()
; Output an OPERATION ERROR character to ATARIBUS.
; No result
;
putlp: call outrdy$ ;ok to send?
jz putlp ;uh uh
mvi a,ERR ;send the error char
call outch$
ret
endfunc
function aputnak
external outrdy$,outch$
;************************************************
; aputnak ()
; Output a NEGATIVE ACKNOWLEDGEMENT character
; to ATARIBUS. No result.
;
putlp: call outrdy$ ;ok to send?
jz putlp ;uh uh
mvi a,NAK ;send the nak char
call outch$
ret
endfunc
;***************************************************
;
; SYSTEM DEPENDENT ROUTINES
;
; All the following functions must be changed for
;different systems and may only alter register A
;and possibly the flag bits.
;
;NOTE that the "ainit" function at the top of this
; file must alse be changed!
;
;***************************************************
function cmdf$
;***************************************************
; Return Z flag = 0 if CMD- line is asserted (TRUE)
; else return Z flag = 1.
;
in acstat ;CMD status port
ani ACMDFB ;set Z flag
ret
;
ds 11 ;*extra space*
;
endfunc cmdf$
function gotch$
;***************************************************
; Return Z flag = 0 if char has been received else
; return Z flag = 1.
;
in astat ;data status port
ani ARCVDB ;set Z flag
ret
;
ds 11 ;*extra space*
;
endfunc gotch$
function inch$
;***************************************************
; Return received data char in A reg.
;
in adata
ret
;
ds 13 ;*extra space*
;
endfunc inch$
function outrdy$
;***************************************************
; Return Z flag = 0 if it's ok to output a character
; else return Z flag = 1.
;
in astat ;data status
ani AXRDYB ;set Z flag
ret
;
ds 11 ;*extra space*
;
endfunc outrdy$
function outch$
;***************************************************
; Output char from A reg to ATARI interface port
;
out adata
ret
;
ds 13 ;*extra space*
;
endfunc outch$
function cls
external puts
;***************************************************
; Clear the terminal screen.
;
;FOLLOWING INSTRUCTION MUST BE FIRST SO THAT
;'ASINSTAL' CAN PICK UP THE STRING ADDRESS:
lxi h,clrstr ;address of string
;
push h
call puts ;output string
pop d ;drop arg
ret
;
ds 7 ;*extra space*
;
clrstr: db 1Ah,0 ;string to clear screen
db 0,0,0,0,0,0 ;*extra space*
;
endfunc cls