home *** CD-ROM | disk | FTP | other *** search
- /* ExcTranf.c : exchange, block transfer and search block
- * instructions emulation.
- *
- * Copyright 1996 Rui Fernando Ferreira Ribeiro.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- /*
- * History:
- * 5th April 96:
- * . Modified IX/IY logic
- */
-
- #include "env.h"
-
- /*=========================================================================*
- * ex_de_hl *
- *=========================================================================*/
- void ex_de_hl()
- {
- LOCAL USHORT tmp;
-
- T(4);
- tmp = HL;
- HL = DE;
- DE = tmp;
- }
-
- /*=========================================================================*
- * ex_de_ix *
- *=========================================================================*/
- void ex_de_ix()
- {
- LOCAL USHORT tmp;
-
- T(8);
- /*tmp = IX; */ /* since in comp.sys.sinclair they disagree... */
- tmp = HL;
- /*IX = DE; */
- HL = DE;
- DE = tmp;
- }
-
- /*=========================================================================*
- * ex_de_iy *
- *=========================================================================*/
- void ex_de_iy()
- {
- LOCAL USHORT tmp;
-
- T(8);
- /* tmp = IY; */
- tmp = HL;
- /* IY = DE; */
- HL = DE;
- DE = tmp;
- }
-
- /*=========================================================================*
- * ex_af_af2 *
- *=========================================================================*/
- void ex_af_af2()
- {
- LOCAL USHORT tmp;
-
- T(4);
- build_F();
- tmp = AF;
- AF = AF2;
- AF2 = tmp;
- read_F();
- }
-
- /*=========================================================================*
- * exx *
- *=========================================================================*/
- void exx()
- {
- LOCAL USHORT tmp;
-
- T(4);
- tmp = BC;
- BC = BC2;
- BC2 = tmp;
- tmp = DE;
- DE = DE2;
- DE2 = tmp;
- tmp = HL;
- HL = HL2;
- HL2 = tmp;
- }
-
- /*=========================================================================*
- * ex_psp_hl *
- *=========================================================================*/
- void ex_psp_hl()
- {
- LOCAL USHORT tmp;
-
- T(19);
- tmp = HL;
- HL = pop();
- push(tmp);
- }
-
- /*=========================================================================*
- * ex_psp_ix *
- *=========================================================================*/
- void ex_psp_ix()
- {
- LOCAL USHORT tmp;
-
- T(23);
- tmp = IX;
- IX = pop();
- push(tmp);
- }
-
- /*=========================================================================*
- * ex_psp_iy *
- *=========================================================================*/
- void ex_psp_iy()
- {
- LOCAL USHORT tmp;
-
- T(23);
- tmp = IY;
- IY = pop();
- push(tmp);
- }
-
-
- /*=========================================================================*
- * ldi *
- *=========================================================================*/
- void ldi()
- {
- #define ldi \
- T(16); \
- writebyte(DE++, readbyte(HL++) ); \
- flags._P = --BC; \
- flags._H = flags._N = 0;
-
- ldi
- }
-
- /*=========================================================================*
- * ldir *
- *=========================================================================*/
- void ldir()
- {
- /* This block is not really needed ---
- just here to speed up emulation
- */
- if(BC > 3)
- {
- LOCAL USHORT tmp;
-
- /* calculate time for next interrupt
- */
- if((tmp=clock_ticks/16)>BC)
- tmp = BC;
-
- while(tmp > 1)
- {
- /* If LDIR would auto-modify its on opcode, will have to leave
- */
- if((HL - PC) < 2)
- break;
- writebyte(DE++, readbyte(HL++));
- BC--;
- tmp--;
- }
- }
- /* The instruction would work only with the following code
- */
- ldi
- if(BC)
- {
- T(5);
- PC -= 2;
- }
- }
-
- #undef ldi
-
- /*=========================================================================*
- * ldd *
- *=========================================================================*/
- void ldd()
- {
- #define ldd \
- T(16); \
- writebyte(DE--, readbyte(HL--) ); \
- flags._P = --BC; \
- flags._H = flags._N = 0;
-
- ldd
- }
-
- /*=========================================================================*
- * lddr *
- *=========================================================================*/
- void lddr()
- {
- /* This block is not really needed ---
- just here to speed up emulation
- */
- if(BC > 3)
- {
- LOCAL USHORT tmp;
-
- /* calculate time for next interrupt
- */
- if((tmp=clock_ticks/16)>BC)
- tmp = BC;
-
- while(tmp > 1)
- {
- /* If LDDR would auto-modify its on opcode, will have to leave
- */
- if((PC - HL) < 2)
- break;
- writebyte(DE--, readbyte(HL--));
- BC--;
- tmp--;
- }
- }
- /* The instruction would work only with the following code
- */
- ldd
- if(BC)
- {
- T(5);
- PC -= 2;
- }
- }
-
- #undef ldd
-
- /*=========================================================================*
- * cpi *
- *=========================================================================*/
- void cpi()
- {
-
- #define cpi \
- LOCAL UCHAR tmp, n; \
- \
- T(16); \
- flags._N = 1; \
- \
- /* cp_phl ∩inline∩ */ \
- flags._H = (((n = readbyte(HL)) & 0xF) > (A & 0xF)); \
- flags._Z = !(tmp = (UCHAR)((UCHAR)A - (UCHAR)n)); \
- flags._C = (n > A); \
- flags._S = (tmp & BIT_7); \
- /* -------------------------- */ \
- flags._P = --BC; \
- HL++; \
- flags._X = tmp & (UCHAR)BIT_5; \
- flags._Y = tmp & (UCHAR)BIT_3;
-
- cpi
- }
-
- /*=========================================================================*
- * cpir *
- *=========================================================================*/
- void cpir()
- {
- cpi
- if(BC && !flags._Z)
- {
- T(5);
- PC -= 2;
- }
- }
-
- #undef cpi
-
- /*=========================================================================*
- * cpd *
- *=========================================================================*/
- void cpd()
- {
- #define cpd \
- LOCAL UCHAR tmp, n; \
- \
- T(16); \
- flags._N = 1; \
- flags._H = (((n = readbyte(HL)) & 0xF) > (A & 0xF)); \
- flags._Z = !(tmp = (UCHAR)((UCHAR)A - (UCHAR)n)); \
- flags._C = (n > A); \
- flags._S = (tmp & BIT_7); \
- flags._P = --BC; \
- HL--; \
- flags._X = tmp & (UCHAR)BIT_5; \
- flags._Y = tmp & (UCHAR)BIT_3;
-
- cpd
- }
-
- /*=========================================================================*
- * cpdr *
- *=========================================================================*/
- void cpdr()
- {
- cpd
- if(BC && !flags._Z)
- {
- T(5);
- PC -= 2;
- }
- }
-
- #undef cpd
-
- /* EOF: ExcTranf.c */
-