module serio; { A set of procedures and functions for the Apple II version of CP/M which do I/O via 'COMM' cards (or their equivalent) put into various slots. } const slot = 2; { slot card is in } base = $E08E; { base address for ACIA's } procedure poke(ch:byte;add:integer); { Puts 'ch' into the absolute address, 'add' } begin inline ("LDA / ch / "LHLD / add / $77 ); { MOV M,A } end; function peek (add:integer): byte; { Returns the value of the byte located at the absolute address, 'add' } var value:integer; begin inline ( "LHLD/ add / $7E / { MOV A,M } "STA / value ); peek := value; end; procedure initac; { Initializes the ACIA in the slot } var status: integer; begin status := base + slot *16; inline ("LHLD/ status / $3E / $03 / { MVI A,03 } $77 / { MOV M,A } $3E / $11 / { MVI A,11 } $77 ); { MOV M,A } end; (* initac *) function serin: char; { Returns the byte which has just been received. NOTE: it will stay forever in this routine if a byte has NOT been received } const rxmask = $01; { mask for receive buffer full } var status, data: integer; begin status := base + slot*16; data := status+1; repeat until (peek(status) & rxmask ) <> 0; serin := peek( data ); end; procedure serout(ch: char); { Sends the character, 'ch', out } const txmask=$02; { mask for transmit buffer empty } var data, status: integer; begin status := base + 16*slot; data := status + 1; repeat until (peek(status) & txmask ) <> 0; poke (ch,data); end; (* serout *) modend.