{PCP.INC contains primitive routines to communicate between the PCPI Z80 card (Applicard) and the Franklin or Apple. Copyright 1984 by N.T.Carnevale. Permission granted for nonprofit use.} {Include before any APLGR file. Variables and constants which are to be hidden from the user's programs start with an underscore} CONST {ports} _HOSTOUT=0; _HOSTIN=$20; _HOSTSTAT=$40; {commands to transfer more than one byte} _RDHOST=1; {Z80 -> 6502} _WRHOST=2; {6502 -> Z80} {commands for single byte transfers--vers.9 of PCPI ROM} _RDBYTE=6; _WRBYTE=7; {command for 6502 to execute a procedure} _CALL=3; {********************************************************** These three routines are low level "primitives" that should probably never be called from procedures outside this file} FUNCTION _recvbyte:byte; {get a byte from the 6502} CONST READY=$80; BEGIN WHILE (READY AND port[_HOSTSTAT]) = 0 DO ; {wait til ready} _recvbyte:=port[_HOSTIN]; {get byte} END; PROCEDURE _sendbyte(datum:byte); {send a byte to 6502} CONST BUSY=1; BEGIN WHILE (BUSY AND port[_HOSTSTAT]) <> 0 DO ; {wait til ready} port[_HOSTOUT]:=datum; {send byte} END; PROCEDURE _sendword(data:integer); {send a word (low byte first) to the 6502} VAR a:RECORD CASE boolean OF TRUE: (i:integer); FALSE: (b:array [1..2] of byte); END; BEGIN a.i:=data; _sendbyte(a.b[1]); _sendbyte(a.b[2]); END; {********************************************************** Now the blocks which may be referenced by other ones} FUNCTION _rdhostbyte(apladdr:integer):byte; {get a byte from the 6502's RAM at address apladdr} BEGIN _sendbyte(_RDBYTE); _sendword(apladdr); _rdhostbyte:=_recvbyte; {get data} END; PROCEDURE _wrhostbyte(apladdr:integer; datum:byte); {send a byte to address apladdr in the 6502's RAM} BEGIN _sendbyte(_WRBYTE); _sendword(apladdr); _sendbyte(datum); END; PROCEDURE _rdhostdata(sourceaddr,destaddr,bufsize:integer); {transfers bufsize bytes from the 6502's RAM to the Z80's RAM. Arguments are the starting addresses of the source and destination, and length of the buffer area which is to receive the data. Call thusly: _rdhostdata(apladdr,ADDR(buffer),SIZEOF(buffer)); } VAR i:integer; b:^byte; BEGIN _sendbyte(_RDHOST); _sendword(sourceaddr); _sendword(bufsize); b:=PTR(destaddr); FOR i:=bufsize DOWNTO 1 DO BEGIN b^:=_recvbyte; b:=PTR(ORD(b)+1); END; END; PROCEDURE _wrhostdata(sourceaddr,destaddr,bufsize:integer); {transfers bufsize bytes from the Z80's RAM to the 6502's RAM. Arguments are the starting addresses of the source and destination, and length of the buffer area which is to receive the data. Call thusly: _wrhostdata(ADDR(buffer),apladdr,SIZEOF(buffer)); } VAR i:integer; b:^byte; BEGIN _sendbyte(_WRHOST); _sendword(destaddr); _sendword(bufsize); b:=PTR(sourceaddr); FOR i:=bufsize DOWNTO 1 DO BEGIN _sendbyte(b^); b:=PTR(ORD(b)+1); END; END; PROCEDURE _callapl(apladdr:integer); {executes routine in the 6502's RAM starting at apladdr. This routine must end with a "return" command. NOTE: for locations > 32K, either use negative integers or hex constants} BEGIN _sendbyte(_CALL); _sendword(apladdr); END; {end of PCP.INC}