A85: Link port routines


[Prev][Next][Index][Thread]

A85: Link port routines



Here is the small c link routine that was previously requested. I apologize
for the delay. The routines are based on the getsend.asm source available
at ticalc.org, originally written by Pascal.

** I do have one question though. In the _Test_Break routine, I read in
from port (3), and check bit 3 to see if the ON key is currently pressed.
Since the ON key generates an interrupt, will this bit ever be set outside
of the context of an interrupt routine?

These functions have not been tested, but they appear to be sound. Let me
know if they help.

Jeremy
#ifndef LINK_C
#define LINK_C
/* This is a small c wrapper function for Pascal's get/send routines (with
   slight modifications)

   Functions:
   o get_byte() returns a byte (char)
   o send_byte(char) sends a byte

   Usage:
   o call these functions to send and receive data over the link port
   o if the user presses ON, the functions return with link_err set to 1.

   Notes:
   o you may want to customize the error-checking routine (at the bottom)

Header from getsend.asm:
; That is my 2 routines I use to send and to receive a byte via link-port

; They are maybe not optimized , but they are free bugs : I use them in
; several progs (SEND92 / ZPONG / SEND-ROM ...)

; You must write a break routine , in case of error. If you want I can send an
; example , but it's very easy to do !

; Pascal
*/

// error variable, set to 1 on error (user presses 'ON' key)
char link_err;
 
// Small c function header
get_byte() {
   link_err = 0;
#asm


;-------------------------------------------------
;                   Rece_byte
;-------------------------------------------------
; INPUT   : NONE
; OUTPUT  : a           = Read byte value
   push bc
   push de
   ld  e,1       ; for the OR
   ld  c,0       ; byte receive
   ld  b,8       ; counter
   ld  a,$C0
   out   (7),a
_rb_w_Start:
   in  a,(7)
   and 3
   cp  3
   jr  nz,_rb_get_bit
   call &_Test_Break
   jr  _rb_w_Start
_rb_get_bit:
   cp  2
   jr  z,_rb_receive_zero
   ld  a,c
   or  e
   ld  c,a
   ld  a,$D4
   out (7),a
   jr  _rb_waitStop

_rb_receive_zero:
   ld  a,$E8
   out (7),a
_rb_waitStop:
   call &_Test_Break
   in  a,(7)
   and 3
   jr  z,_rb_waitStop
   ld  a,$c0
   out (7),a
   rl  e
   djnz _rb_w_Start
   ld  a,c
   pop de
   pop bc

; put return value in hl (per the small c interface)

   ld  l,a
   xor a
   ld  h,a
#endasm
}

// Small c function header
send_byte(byte) char byte; {
   link_err = 0;
#asm
   ; grab the argument off the stack, put it in 'a'
   ld  hl,2
   add hl,sp
   ld  a,(hl)

;-------------------------------------------------
;                    Send_byte
;-------------------------------------------------
; INPUT   : a
; OUTPUT  : NONE
   push bc
   ld  b,8
   ld  c,a  ;byte to send
   ld  a,$C0
   out (7),a
_w_setport3:
   in  a,(7)
   and 3
   cp  3
   jr  z,_calc_bit
   call &_Test_Break
   jr  _w_setport3
_calc_bit:
   ld  a,c
   and 1
   jr  z,_send_one
_send_zero:
   ld  a,$E8
   out (7),a
   jr  _wait_setport
_send_one:
   ld  a,$D4
   out (7),A
_wait_setport:
   call &_Test_Break
   in  a,(7)
   and 3
   jr  nz,_wait_setport
   ld  a,$C0
   out (7),A
   srl c
   djnz _w_setport3
   pop bc

#endasm
}

// Stand-alone routine to test if the ON key has been pressed, terminating
// the function called by both get_byte() and send_byte()

#asm
_Test_Break :

; [Insert here your break routine]
   in  a,(3)
   bit 3,a
   ret z    ; on not pressed, return normally
   pop bc   ; pop call to _Test_Break
   pop bc   ; pop de (get_byte()) -- pop argument (send_byte())
   pop bc   ; pop bc (get_byte() and send_byte())
   ld  a,1
   ld  (link_err),a
   ret      ; returns to the functions which called [get|send]_byte()

#endasm

#endif

Follow-Ups: