page 255 .z80 global msginit ; global msg.ist,msg.in,msg.ost,msg.out ; global msg.sout global msg.sm,msg.recv extrn bufinit,hwl2phy,phy2log extrn fifolst include config.inc include z180reg.inc dseg mkbuf 0,mtx.fifo,mtx.fifo_len mkbuf 1,mrx.fifo,mrx.fifo_len itx equ 0*2 irx equ 1*2 ;-------------------------------------------------------------- ; ; Init message fifos ; dseg msginit: ld a,(INIDONE) cp INIDONEVAL jr nz,msgi_1 ld hl,(040h) ld a,(040h+2) call phy2log ld a,l or h jr z,msgi_1 ld de,fifolst ld bc,4*2 ldir ret msgi_1: ld a,(043h) ;TODO: value should be 0 ld ix,mtx.fifo call bufinit push ix pop hl call hwl2phy ld (040h),hl ld (040h+2),a ld a,0ffh ld (043h),a out (AVRINT5),a wait: ld a,(043h) or a jr nz,wait ld ix,mrx.fifo jp bufinit ;-------------------------------------------------------------- dseg msgi.st: push ix ld ix,(fifolst+irx) ; buf.empty: ld a,(ix+o.in_idx) ; sub (ix+o.out_idx) ; pop ix ret z or 0ffh ret ;-------------------------------------------------------------- msg.in: push ix ld ix,(fifolst+irx) ; buf.get: ld a,(ix+o.out_idx) ; bg.wait: cp (ix+o.in_idx) ; jr z,bg.wait push hl ; push ix pop hl add a,l ld l,a jr nc,bg.nc inc h bg.nc: ld l,(hl) ld a,(ix+o.out_idx) ; inc a and (ix+o.mask) ld (ix+o.out_idx),a ld a,l pop hl pop ix ret ;---------------------------------------------------------------------- ; Receive message ; ; hl: pointer to receive buffer ; b: receive buffer size ; return: ; data in buffer, buffer[0] has len ; bc, a: destroyed ; TODO: time out ; TODO: return number of stored chars ; TODO: result code msg.recv: push de mr_wait_start: call msg.in cp 0AEh jr nz,mr_wait_start call msg.in ; get message length ld c,a inc c jr mr_do mr_next: dec c jr z,mr_exit ; while chars in input buffer call msg.in ; get next mr_do: ld e,a ld a,b or a ; if room in output buffer jr z,mr_skip ld (hl),e ; store char inc hl dec b mr_skip: jr mr_next ; mr_exit: pop de ret ;-------------------------------------------------------------- msgo.st: push ix ld ix,(fifolst+itx) ; buf.full: ld a,(ix+o.in_idx) ; inc a and (ix+o.mask) sub (ix+o.out_idx) ; pop ix ret z or 0ffh ret ;-------------------------------------------------------------- if 0 msg.out: push ix ld ix,(fifolst+itx) ; push hl ; push bc push ix pop hl ld c,(ix+o.in_idx) ; ld b,0 add hl,bc ld b,a ld a,c ; inc a and (ix+o.mask) bp.wait: cp (ix+o.out_idx) ; jr z,bp.wait ld (hl),b ld (ix+o.in_idx),a ld a,b out (AVRINT5),a pop bc pop hl pop ix ret endif ;-------------------------------------------------------------- if 0 msg.out: push ix ld ix,(fifolst+itx) ; push bc ld c,(ix+o.in_idx) ; ld b,0 push ix ;14 add ix,bc ;10 ld (ix+0),a ;15 pop ix ;12=51 ld b,a ; 4 ld a,c ; inc a ; and (ix+o.mask) ; bp.wait: cp (ix+o.out_idx) ; jr z,bp.wait ; ld (ix+o.in_idx),a ; ld a,b out (AVRINT5),a pop bc pop ix ret endif ;-------------------------------------------------------------- if 0 ; Works only, if buffer size < (128 - 3) ; --> mask must be 03fh or less msg.out: push ix ld ix,(fifolst+itx) ; push bc ld b,a ; 4 ld a,(ix+o.in_idx) ;14 ld ($ + 3 + 2),a ;15 ld (ix+0),b ;15 inc a ; and (ix+o.mask) ; bp.wait: cp (ix+o.out_idx) ; jr z,bp.wait ; ld (ix+o.in_idx),a ; ld a,b out (AVRINT5),a pop bc pop ix ret endif ;-------------------------------------------------------------- ; ; (hl): data if 0 msg.sout: push ix ;14 ld ix,(fifolst+itx) ;12 push bc ;11 push de ;11 ld c,(hl) ; 6 ld b,0 ; 6 inc hl ; 7 ms.ol: ; \ TODO: ld a,low mtx.fifo ; 6 does not work with DR LINK-80 --> (fifolst+itx+0) add a,(ix+o.in_idx) ;14 ld e,a ; 4 ld a,high mtx.fifo ; 6 does not work with DR LINK-80 --> (fifolst+itx+1) adc a,b ; 4 ld d,a ; 4 ld a,(ix+o.in_idx) ;14 inc a ; 4 and (ix+o.mask) ;14 ms.wait: cp (ix+o.out_idx) ;14 jr z,ms.wait ; 6/8 ldi ;12 ld (ix+o.in_idx),a ;15 jp pe,ms.ol ; 6/9 -- 126 out (AVRINT5),a ;10 pop de ; 9 pop bc ; 9 pop ix ;12 ret ; 9 endif ;-------------------------------------------------------------- ; ; (hl): data if 1 msg.sout: push ix ;14 ld ix,(fifolst+itx) ;12 push bc ;11 push de ;11 ld b,(hl) ; 6 inc hl ; 4 ex de,hl ; 3 ms.ol: ; \ push ix ;14 pop hl ; 9 ld c,(ix+o.in_idx) ;14 ld a,c ; 4 add l ; 4 ld l,a ; 4 jr nc,ms.on ; 6/8 inc h ; 4 ms.on: ld a,c ; 4 inc a ; 4 and (ix+o.mask) ;14 ms.wait: cp (ix+o.out_idx) ;14 jr z,ms.wait ; 6/8 ld c,a ; 4 ld a,(de) ; 6 inc de ; 4 ld (hl),a ; 7 ld (ix+o.in_idx),c ;15 djnz ms.ol ; 7/9 -- 130 out (AVRINT5),a ;10 ex de,hl ; 3 pop de ; 9 pop bc ; 9 pop ix ;12 ret ; 9 endif ;---------------------------------------------------------------------- ; Send message ; b: msg length ; hl: pointer to message (netto) msg.snd: push ix ld ix,(fifolst+itx) ld c,0AEh call buf.put msnd_l: ld c,(hl) inc hl call buf.put djnz msnd_l pop ix ret ;---------------------------------------------------------------------- ; ; Put char in message buffer: ; ix: buffer to put into ; c: char buf.put: push ix ;15 push bc ;11 ld a,(ix+o.in_idx) ;19 ld c,a ;4 ld b,0 ;7 add ix,bc ;11 pop bc ;10 ld (ix),c ;7 pop ix ;14 inc a ;4 and (ix+o.mask) ;19 =121 bufp.wait: cp (ix+o.out_idx) ;19 jr z,bufp.wait ;12/7 ld (ix+o.in_idx),a ;19 out (AVRINT5),a ;11 ld a,c ;4 ret ;10 =191 ;---------------------------------------------------------------------- ; Send message MEMORY ; ; hl: pointer to message (netto) ; b: msg length msg.sm: push ix ld ix,(fifolst+itx) ld c,0AEh call buf.put ld c,b call buf.put msm_l: ld c,(hl) inc hl call buf.put djnz msm_l pop ix ret ;---------------------------------------------------------------------- ; Send message INLINE ; ; h: function ; l: subfunction ; b: msg length if 0 msg.sil: ex (sp),hl push ix ld ix,(fifolst+itx) ld c,0AEh call buf.put ld b,(hl) msnd_pl: ld c,(hl) inc hl call puf.put djnz msnd_pl ex (sp),hl pop ix ret endif ;-------------------------------------------------------------- if 0 msg.co: push af push hl ld (buf_char),a ld hl,buf call msg.sout pop hl pop af ret buf: db buf_end - $ - 1 ;output string length db 0AEh ; message start token db buf_end - $ - 1 ; message length db 1 ; command db 1 ; subcommand buf_char: db 0 ; pay load buf_end: endif ;-------------------------------------------------------------- end