Chương trình đưa data ra Ram chung, Debug, Dump, Run.

Một phần của tài liệu 20101005022225_lvmmt10 (Trang 86 - 135)

Chương V Chương trình nguồn

5.1. Chương trình đưa data ra Ram chung, Debug, Dump, Run.

/*===================LUẬN VĂN TỐT NGHIỆP===================== - Chương trình được viết trên Turbo C++ Version 3.0.

- Đề tài: Giao tiếp giữa PC & KIT Z80 qua LPT1. - Giáo viên hướng dẫn: Thầy Nguyễn Xuân Minh. - Người viết: Lưu Đình Dũng.

- Ngày viết: 11-03-1999.

- Cập nhật lần cuối: 30-06-1999

- Chú ý: Dòng đầu tiên của chương trình phải đượcc khai báo bằng lệnh: - ld sp,xxxxh ============================================================*/ #include <dos.h> #include <stdio.h> #include <io.h> #include <conio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> /*== Typedefs =================================================*/ typedef unsigned char byte;

typedef

struct addr{ byte lo; byte hi; };

/*== Các pin tương ứng của 74LS374================================== NC CS8255 /OER CS244 EWT /CER A1 A0

D7 D6 D5 D4 D3 D2 D1 D0

============================================================*/ /*== Constants =================================================*/ #define BasicADDR 0x378 /*Địa chỉ cổng máy in*/

#define DataREG BasicADDR /*Địa chỉ thanh ghi data*/ #define StateREG BasicADDR + 1 /*Địa chỉ thanh ghi trạng thái*/ #define CTRLREG BasicADDR + 2 /*Địa chỉ thanh ghi điều khiển*/

//============================================================

#define Init374 0xD7/*ENB=1,CS8255=1,/OER=0,CS244=1,EWT=0,/CER=1,A1=1,A0=1*/ /*1101 0111*/

#define Init8255 0x97/*ENB=1,CS8255=0,/OER=0,CS244=1,EWT=0,/CER=1,A1=1,A0=1*/ /*1001 0111*/

#define WRPortA 0x94/*ENB=1,CS8255=0,/OER=0,CS244=1,EWT=0,/CER=1,A1=0,A0=0*/ /*1001 0100*/

#define WRPortC 0x96/*ENB=1,CS8255=0,/OER=0,CS244=1,EWT=0,/CER=1,A1=1,A0=0*/ /*1001 0110*/

#define RDPortA 0x94/*ENB=1,CS8255=0,/OER=0,CS244=1,EWT=0,/CER=1,A1=0,A0=0*/ /*1001 0100*/

#define RDPortC 0x96/*ENB=1,CS8255=0,/OER=0,CS244=1,EWT=0,/CER=1,A1=1,A0=0*/ /*1001 0110*/

#define ENBRAM 0xD3/*ENB=1,CS8255=1,/OER=0,CS244=1,EWT=0,/CER=0,A1=1,AO=1*/ /*1101 0011*/

#define GetStart 0x67/*ENB=0,CS8255=1,/OER=1,CS244=0,EWT=0,/CER=1,A1=1,AO=1*/ /*0110 0111*/

//=============================================================

#define GetDebug 0x4F/*ENB=0,CS8255=1,/OER=0,CS244=0,EWT=1,/CER=1,A1=1,A0=1*/ /*0100 1111*/

#define ClearEWT 0x67/*ENB=0,CS8255=1,/OER=1,CS244=0,EWT=0,/CER=1,A1=1,A0=1*/ /*0110 0111*/

#define EnbRAM 0x6F/*ENB=0,CS8255=1,/OER=1,CS244=0,EWT=1,/CER=1,A1=1,A0=1*/ /*0110 1111*/

#define RDPA 0x8C/*ENB=1,CS8255=0,/OER=0,CS244=0,EWT=1,/CER=1,A1=0,A0=0*/ /*1000 1100*/

#define RDPC 0x8E/*ENB=1,CS8255=0,/OER=0,CS244=0,EWT=1,/CER=1,A1=1,A0=0*/ /*1000 1110*/

#define RDREG 0xCF/*ENB=1,CS8255=1,/OER=0,CS244=0,EWT=1,/CER=1,A1=1,A0=1*/ /*1100 1111*/

#define RDData 0xEF/*ENB=1,CS8255=1,/OER=1,CS244=0,EWT=1,/CER=1,A1=1,A0=1*/ /*1110 1111*/

//============================================================= /*Giá trị thực*/ /*N/d CTRLREG*/

#define InitCTRL 0x10 /*SLCTIN=1;INIT=0;AF=1;STB=1 -> 0001 0000*/ #define GenSLCTIN 0x18 /*SLCTIN=0;INIT=0;AF=1;STB=1 -> 0001 1000*/ #define SubGen 0x1A /*SLCTIN=0;INIT=0;AF=0;STB=1 -> 0001 1010*/ #define GENSTB 0x11 /*SLCTIN=1;INIT=0;AF=1;STB=0 -> 0001 0001*/ #define GENINIT 0x14 /*SLCTIN=1;INIT=1;AF=1;STB=1 -> 0001 0100*/ #define GENAF 0x12 /*SLCTIN=1;INIT=0;AF=0;STB=1 -> 0001 0010*/ #define GENSTBLOW 0x19 /*SLCTIN=0;INIT=0;AF=1;STB=0 -> 0001 1001*/ #define GENSTBHI 0x11 /*SLCTIN=1;INIT=0;AF=1;STB=0 -> 0001 0001*/ //=============================================================

#define Mode0_Out 0x80 /*PA=PB=PC=Output,Mode 0, 1000 0000*/ #define Mode0_In 0x9B /*PA=PB=PC=Input, Mode 0, 1001 1011*/ //Các độ rộng xung #define Tlatch 3/1000 #define Twr 3/1000 #define Tgen 3/1000 #define Set 3/1000 //*==Các giá trị khác=============================================*/ #define TxNumber 144 #define countDump 18 #define TEXT_ATTR 0x1E #define MENU_ATTR 0x70 #define HIGH_ATTR 0x20 #define MSG_ATTR 0x3E #define RED_ATTR 0x4F #define ROSE_ATTR 0x5F #define END_STR 0x00 #define CALL 0xCD #define RET 0xC9 #define JUMP 0xC3 /*==Các hàm propotype===========================================*/ void Latch374(void); void INIT(void); void WRITE(void);

void INIT8255(void); void OutPortA(byte); void OutPortC(byte); void WriteRAM(byte); byte ReadLow(void); byte ReadHigh(void); byte ReadRAM(void); void WriteRAM(byte!; int cmp(byte,byte); void Read8255(void); void Pseudo(void); void GetToStart(void); void ERROR1(byte,byte,byte,byte); void ERROR2(void); void Stereo(int); void GetToDebug(void); void SetWAIT(void); byte RDError(void); byte RDBusy(void); byte RD_LoAddr(void); byte RD_HiAddr(void); byte ReadReg(byte,byte,byte,byte); void GetCont(void); void GetToCont(void); byte Check(FILE *,char *); addr OutKIT(byte,byte,FILE *); void ReadRegister(char VarName); void SetWAITDebug(byte); void ErrorReg(byte,byte); void PrintAddr(byte,byte,int); byte KiemTra(byte,byte); void EnableRAM(void); byte FirstM1(void);

int FileLst(char Lst[81],byte,byte); void UpdateScreen(void);

int LineToAddr(char Lst[81]); void error_debug(void); void msg_debug(void); void msg_toolbar(void); void msg_finish(void); void error_file(char *); byte CallRet_Ins(void); byte Dump(byte,byte,byte,byte,byte,byte,byte,byte); addr SearchM1(void); byte ReadMem(void); void PrintMemory(byte,int,byte,byte); void Menu_Mem(void); addr input_addr_dump_start(void); addr input_addr_dump_end(void); void msgError1(void); void msgWait(void); void ServiceCall(void); /*===========================================================*/ /*=====================CHƯƠNG TRÌNH CHÍNH===================*/ /*===========================================================*/ extern char text[500][81];

extern unsigned win_index; extern int arr_bp;

extern unsigned x, y;

extern char string_y[5],string_x[3];

char toolbar_debug[44]={" F7 Trace into F8 Step over ESC Quit"}; int ArrReg[25];

main1(char Filename[81],byte LuaChon,int Key) { /*==============*/ /*==Phần khai báo==*/ /*==============*/ addr DiaChi,StartAddr,TempAddr,AddrDump,BinAddr; addr AddrStart,AddrEnd; byte ReturnAddrLo,ReturnAddrHi; byte LoAddr,HiAddr;

byte ErrorYes,BusyYes; byte TempLoAddr=0x00,TempHiAddr=0x00; byte AddrFlag=0; byte FError=0,DumpError=0; byte KT; byte InvalidM1=1,CycleM1,CycleOld; byte Flag_bp=1; byte Flag_call=0; byte InvalidFlag=0; byte DStartLoAddr,DStartHiAddr,DEndLoAddr,DEndHiAddr; int m,CurrentLine,OldLine,TempLine,SubLine; int Dia_chi,Addr4byte=0,Hi; int j,k; FILE *fp; char TenFile[81]; byte CheckOk; /*=================*/ /*==Phần chương trình==*/ /*=================*/

INIT(); // Khởi động 374: Reset Z80, cấm các CS. INIT8255(); // Khởi động 8255: Mode 0, PA=PB=PC: Output. fp = fopen(Filename,"rb"); // Open Filename.bin.

CheckOk=Check(fp,Filenaae); // Kiểm tra file có hợp lệ không?. if (CheckOk==0) return(0);

/* Địa chỉ bắt đầu load data ra RAM chung */ StartAddr.hi=0X00;

StartAddr.lo=0X00;

/* Hàm OutKIT trả về byte đ/c thấp + byte đ/c cao của phần bắt đầu chương trình đọc thanh ghi */ DiaChi=OutKIT(StartAddr.lo,StartAddr.hi,fp); if ( (DiaChi.lo==0)&&(DiaChi.hi==0) ) return(0); /* Đ/c bắt đầu của c/t đọc t/ghi */

ReturnAddrLo=DiaChi.lo; ReturnAddrHi=DiaChi.hi; fclose(fp);

/* Đưa chương trình đọc thanh ghi ra RAM chung (rdreg.bin) */ fp = fopen("rdreg.bin","rb");

CheckOk=Check(fp,"rdreg.bin"); if (CheckOk==0) return(0);

/* Bắt đầu tại đ/c ReturnAddrHiReturnAddrLo */ TempAddr=OutKIT(ReturnAddrLo,ReturnAddrHi,fp); if ( (TempAddr.lo==0)&&(TempAddr.hi==0) ) return(0); fclose(fp);

/* Đưa chương trình dump memory ra RAM chung (dump.bin) */ fp = fopen("dump.bin","rb");

CheckOk=Check(fp,"dump.bin"); if (CheckOk==0) return(0);

/* Bat dau tai d/c TempAddr.HiTempAddr.Lo */ BinAddr=OutKIT(TempAddr.lo,TempAddr.hi,fp); if ( (BinAddr.lo==0)&&(BinAddr.hi) ) return(0); fclose( fp );

/* Đọc giả 8255 để các port A,B,C trở thành ngõ vào */ Read8255();

Pseudo();

/*==============================*/ /*==Chạy ở chế độ Debug (LuaChon=1)==*/ /*==============================*/ if ( LuaChon==1 )

{

msg_toolbar(); // In thông báo cuối màn hình. /* Thay file.bin (Filename) = file.lst */

m=strlen(Filename); memcpy(TenFile,Filename,m-3); TenFile[m-3]=END_STR; strcat(TenFile,"lst"); Dia_chi=LineToAddr(TenFile); if (Dia_chi) // Địa chỉ hợp lệ. {

GetToDebug(); // Đưa Z80 vào chế độ WAIT (EWT='1'). clear_screen(0,20,80,4,MSG_ATTR);

msg_debug(); // In thông báo.

do // (while key!=ESC) khi có tín hiệu truy xuất RAM chung (CSROM) {

while ( ( Key!=K_F7 ) && ( Key != K_F8 ) && ( Key != K_ESC ) ) { Key=get_key(); }; if ( Key==K_ESC ) break; j=0; // Chờ đọc tín hiệu ERROR. do {

ErrorYes=RDError(); // Đọc tín hiệu ERROR. if ( ErrorYes ) break; // Nếu có -> thoát.

delay(Set); // Nếu không -> chờ 3 micro second. j++; /* Nếu chưa có ERROR thì CPU có thể đang trong 2 case:

1. Chu kỳ I/O 2. Đang bị treo */

if ( ( j==10 ) && ( !RDError() ) ) { j=0; SetWAIT(); }; } while ( ErrorYes == 0 );

/* Cho byte cuối cùng ( ReadReg() ) */ if ( AddrFlag ) { outportb(CTRLREG,InitCTRL); delay(Set); EnableRAM(); }; for (k=1;k<=3;k++) { BusyYes=RDBusy();

if ((BusyYes)&&(k>=2)) break; // Đọc 2 lần để chống nhiễu. delay(Set);

};

/* Nếu lúc này là chu kỳ M1 (BUSY=1) đầu tiên thì: 1. Tiến hành đọc trạng thái các thanh ghi

2. Kiểm tra để nhảy tới breakpoint */ if ( (BusyYes) && (Flag_bp) )

{ /* Đọc địa chỉ = PC đang được đưa vào RAM Đ/c này = điểm thực hiện JP HiAddrLoAddr */ LoAddr=RD_LoAddr(); HiAddr=RD_HiAddr(); Hi=HiAddr*256; Addr4byte=Hi+LoAddr; CycleM1=FirstM1(); if (Dia_chi==Addr4byte) Flag_bp=0; };

if ( ( BusyYes ) && (!Flag_bp) ) {

KT=KiemTra( TempLoAddr,TempHiAddr ); // Sai -> KT=1. /* Nếu lệnh này chưa thi hành đọc t/ghi hoặc đọc rồi nhưng bị sai hoặc trước đó không phải là các g.trị: FD, DD, CB, ED */ if ( ( AddrFlag == 0 ) || ( ( AddrFlag == 1 ) && ( KT ) ) ) {

/* Nếu chu kỳ M1 là hợp lệ ( là chu kỳ M1 thứ nhất ) */ if ( InvalidM1 )

{

CycleOld=CycleM1; CycleM1=FirstM1();

/* Đánh dấu chu kỳ M1 tiếp sau sẽ không hợp lệ */ if ( CycleM1==1 ) InvalidM1=0;

/* F8+CALL: SetWAIT() cho đến khi gặp RET */

else if ( (Key==K_F8) && (CycleOld==CALL) ) Flag_call=1; if (Flag_call) { SetWAIT(); ServiceCall(); Flag_call=0; };

/* Nếu chưa thực hiện lệnh hiện tại lần nào */ if ( AddrFlag == 0 )

{ do

{

AddrFlag = 1;

/* Đọc địa chỉ = PC đang đượcc đưa vào RAM Đ/c này = điểm t/hiện JP HiAddrLoAddr */ LoAddr=RD_LoAddr();

HiAddr=RD_HiAddr();

delay(Set); // delay() rồi đọc lại cho chính xác. TempLoAddr=RD_LoAddr();

TempHiAddr=RD_HiAddr();

} while ((TempLoAddr!=LoAddr) || (TempHiAddr!=HiAddr)); }

// Phát lại nếu thực hiện sai lệnh trước đó. else if ( ( AddrFlag == 1 ) && ( KT ) ) {

LoAddr=TempLoAddr; HiAddr=TempHiAddr; };

/*Chương trình đọc trạng thái các thanh ghi*/

/*Đưa LoAddr & HiAddr vào để thực hiện lệnh JP ADDR*/ do

{ //Đ/c JP về ,đ/c JP đi (đoạn c/t đọc t/ghi)

FError=ReadReg(LoAddr,HiAddr,ReturnAddrLo,ReturnAddrHi); } while ( FError==0 );

/*==========================================*/ /*=========Phan hien thi dong dang Debug==========*/ /*===========Input: địa chỉ (HiAddr,LoAddr)=========*/ /*==========================================*/ /*

1. Mở file filename.lst, truyền đ/c HiAddr,LoAddr.

Tìm line có địa chỉ tương ứng, trả về line (CurrentLine). 2. Đ/c chuyển con trỏ tới line t.ứng trong màn hình editor. 3. Highlight.

*/

clear_screen(0,20,80,4,MSG_ATTR); /* Thay file.bin (Filename) = file.lst */

m=strlen(Filename); memcpy(TenFile,Filename,m-3); TenFile[m-3]=END_STR; strcat(TenFile,"lst"); CurrentLine=FileLst(TenFile,HiAddr,LoAddr); set_attr_screen(0,OldLine,80,1,TEXT_ATTR); /* Do file lst: 60 dòng + 2 dòng *.lst -> *.asm: line=line-(line-1)/62*2 */ SubLine=(CurrentLine-1)/62*2; CurrentLine=CurrentLine-SubLine; if ( (CurrentLine<win_index)||(CurrentLine>win_index+18) ) { win_index=CurrentLine-8; UpdateScreen(); clear_screen(0,20,80,4,MSG_ATTR); set_attr_screen(0,0,80,1,MENU_ATTR); } TempLine=CurrentLine - win_index; set_attr_screen(0,TempLine,80,1,MENU_ATTR); OldLine=TempLine; PrintAddr(HiAddr,LoAddr,CurrentLine); Key=get_key(); } // If (InvalidM1). /* Nếu là chu kỳ M1 thứ 2 */

else if ( ( InvalidM1 == 0 ) && ( AddrFlag == 0 ) ) {

InvalidM1=1; SetWAIT(); }

} // if ( (AddrFlag == 0) || ( (AddrFlag == 1) && (KT) ) )

/*Nếu là chu kỳ M1 nhưng đã duyệt qua rồi thì cho CPU chạy tiếp*/ else

{

AddrFlag=0; SetWAIT();

};

} // if ( ( BusyYes ) && (!Flag_bp) )

/* Nếu là chu kỳ đọc bộ nhớ thì SetWAIT để CPU chạy tiếp */ else SetWAIT();

} while ( Key != 27 );

/* Chạy tiếp sau khi thoát khỏi chế độ DEBUG */ GetToCont();

} // else if (Dia_chi==0) else // Báo lỗi + break. {

error_debug(); return 0; }

} //end ( if LuaChon == 1 )

/*==============================*/ /*==Chạy ở chế độ normal (LuaChon=2)==*/ /*==============================*/ else if ( LuaChon==2 )

{

/*Khởi động Z80 để chạy chương trình từ RAM chung (normal mode)*/ GetToStart();

};

msg_finish();

/*Đoạn chương trình dump bộ nhớ*/ do

{

Key=get_key();

while ( ( Key!=K_F3 ) && ( Key != K_ESC ) ) { Key=get_key(); }; if (Key==K_F3) { //Đ/c cần dump: DStartLoAddr,DStartHiAddr,DEndLoAddr,DEndHiAddr GetToDebug(); //Cho phép WAIT, cấm RAM, chờ đọc BUSY

{ AddrStart=input_addr_dump_start(); AddrEnd=input_addr_dump_end(); DStartLoAddr=AddrStart.lo; DStartHiAddr=AddrStart.hi; DEndLoAddr = AddrEnd.lo; DEndHiAddr= AddrEnd.hi; //AddrEnd++ if (DEndLoAddr == 0xFF) { DEndHiAddr++; DEndLoAddr = 0x00; } else DEndLoAddr++; if (DStartHiAddr>DEndHiAddr) msgError1(); else if ( (DStartHiAddr==DEndHiAddr)&&(DStartLoAddr>DEndLoAddr) ) msgError1(); else InvalidFlag=1; } AddrDump=SearchM1(); //Tìm chu kỳ M1 hợp lệ msgWait(); do

{ /*D/c jp về D/c jp tới (đoạn ct dump)*/

DumpError=Dump(AddrDump.lo,AddrDump.hi,TempAddr.lo,TempAddr.hi, DStartLoAddr,DStartHiAddr,DEndLoAddr,DEndHiAddr);

} while ( DumpError==0 ); /*đ/c đầu bộ nhớ, đ/c cuối bộ nhớ*/ GetToCont(); InvalidFlag=0; } } while (Key!=K_ESC); return 0; } /*===========================================================*/

/*==Các chương trình con=========================================*/ /*===========================================================*/

/*==Chương trình con phát âm thanh==*/ void Stereo(int input)

{ int m=1; while ( m<=3 ) { sound(input);delay(200);nosound();delay(300); m++; } }

/*==Chương trình con báo lỗi 01==*/

void ERROR1(byte AddrLow,byte AddrHi,byte DatOut,byte DAT) { if ( (AddrLow) || (AddrHi) ) { Stereo(494); set_cursor_style(0x20,0x20); set_attr_screen(23,11,38,7,RED_ATTR); gotoxy(24,12); puts("");

gotoxy(24,13); puts("  ERROR 1:  ");

gotoxy(24,14); puts("  1. Common RAM 's fail.  ");

gotoxy(24,15); printf("  2. Data transmit: %02X%02X: %02X  ", AddrHi,AddrLow,DatOut);

gotoxy(24,16); printf(" . Data receiver: %02X%02X: %02X ", AddrHi,AddrLow,DAT);

gotoxy(24,17); puts(" Press ESC to QUIT.  "); gotoxy(24,18); puts(" ");

} else {

Stereo(494);

set_cursor_style(0x20,0x20);

set_attr_screen(23,11,8,7,RED_ATTR); gotoxy(24,12); puts("");

gotoxy(24,13); puts(" ERROR 2:  "); gotoxy(24,14); puts(" 1. Power off.  "); gotoxy(24,15); puts(" 2. Jack 25 pin nonconected.  "); gotoxy(24,16); puts(" 3. Hard wave error.  "); gotoxy(24,17); puts(" Press ESC to QUIT.  "); gotoxy(24,18); puts(“");

};

if (getch()==0) getch(); // exit(1);

}

/*==Chương trình con báo lỗi 02==*/ void ERROR2(void) { Stereo(494); set_cursor_style(0x20,0x20); set_attr_screen(23,11,38,5,RED_ATTR); gotoxy(24,12); puts("  ");

gotoxy(24,13); puts(" ERROR 3:  "); gotoxy(24,14); puts(" File is too long.  "); gotoxy(24,15); puts(" Press ESC to QUIT.  "); gotoxy(24,16); puts(“ ");

if (getch()==0) getch(); // exit(0);

}

/*==Chương trình con khởi động Z80 ở chế độ normal==*/ void GetToStart(void)

{

Latch374();

outportb(CTRLREG,InitCTRL); // Đặt trở lại đường CTRL ở g.trị b.đầu }

/*==Chương trình khởi động 8255: MODE 0, PA=PB=PC: input==*/ void Read8255(void)

{

outportb(DataREG,Init8255); // Chọn 8255 Latch374();

outportb(DataREG,Mode0_In); // Ghi từ đ.khiển WRITE();

outportb(DataREG,Init374); // Đặt trở lại giá trị ban đầu cho 374 Latch374();

}

/*==Chương trình con làm phép đọc giả==*/ void Pseudo(void) { outportb(DataREG,RDPortA); Latch374(); /*Phat xung RD*/ outportb(CTRLREG,GENSTBLOW); delay(Tgen); // Delay 3 micro second

outportb(CTRLREG,InitCTRL); // Đặt trở lại đường CTRL ở g.trị b.đầu outportb(DataREG,RDPortC); // Đặt trở lại giá trị ban đầu cho 374 Latch374();

/*Phat xung RD*/

outportb(CTRLREG,GENSTBLOW); delay(Tgen); // Delay 3 micro second

outportb(CTRLREG,InitCTRL); // Đặt trở lại đường CTRL ở g.trị b.đầu outportb(DataREG,Init374); // Đặt trở lại giá trị ban đầu cho 374

Latch374(); }

int cmp(byte R,byte T) {

if (R==T) return(0); else return(1); }

/*==Chương trình con tạo xung cài 374==*/ void Latch374(void)

{

outportb(CTRLREG,GENINIT);

delay(Tlatch); // Delay 3 micro second (Tlatch) outportb(CTRLREG,InitCTRL);

}

/*==Chương trình con khởi động KIT==*/ void INIT(void)

{

outportb(CTRLREG,InitCTRL); // Khởi tạo các xung điều khiển outportb(DataREG,Init374); // Khởi tạo KIT

Latch374(); // Phát xung cài }

/*==Chương trình con tạo xung WR==*/ void WRITE(void)

{

outportb(CTRLREG,GENAF);

delay(Twr); // Delay 3 micro second (Twr)

outportb(CTRLREG,InitCTRL); // Đặt trở lại đường CTRL ở g.trị b.đầu }

/*==Chương trình khởi động 8255: MODE 0, PA=PB=PC: output==*/ void INIT8255(void)

{

outportb(DataREG,Init8255); Latch374();

outportb(DataREG,Mode0_Out); WRITE();

outportb(DataREG,Init374); //Đặt trở lại giá trị ban đầu cho 374 Latch374();

}

/*==Chương trình con xuất byte thấp của địa chỉ ra port A==*/ void OutPortA(byte low)

{

outportb(DataREG,WRPortA); Latch374();

outportb(DataREG,low); WRITE();

outportb(DataREG,Init374); //Đặt trở lại giá trị ban đầu cho 374 Latch374();

}

/*==Chương trình con xuất byte cao của địa chỉ ra port C==*/ void OutPortC(byte high)

{

outportb(DataREG,WRPortC); Latch374();

outportb(DataREG,high); WRITE();

outportb(DataREG,Init374); // Đặt trở lại giá trị ban đầu cho 374. Latch374();

}

/*==Chương trình con tạo xung RD cho RAM & 'L' cho 157==*/ byte ReadLow(void)

{

byte lowvalue;

outportb(CTRLREG,GENSTBLOW); delay(Tgen); // Delay 3 micro second. lowvalue=inportb(StateREG);

outportb(CTRLREG,InitCTRL); // Đặt trở lại đường CTRL ở giá trị ban đầu. return(lowvalue);

}

/*==Chương trình con tạo xung RD cho RAM & 'H' cho 157==*/ byte ReadHigh(void)

{

byte highvalue;

outportb(CTRLREG,GENSTBHI);

delay(Tgen); // Delay 3 micro second. highvalue=inportb(StateREG);

outportb(CTRLREG,InitCTRL); // Đặt trở lại đường CTRL ở giá trị ban đầu. return(highvalue);

}

/*==Chương trình đọc giá trị từ RAM==*/ byte ReadRAM(void) { byte value,lo,hi; outportb(DataREG,ENBRAM); Latch374(); /*Đọc 4 bit thấp*/ lo=ReadLow();

lo=lo & 0xF0; // 1111 0000: Xoá 4 bit thấp của thanhh ghi trạng thái. lo=lo/16; // Dịch phải 4 bit.

/*Đọc 4 bit cao*/ hi=ReadHigh();

hi=hi & 0xF0; // 1111 0000: Xoá 4 bit thấp của thanhh ghi trạng thái. value=hi+lo;

outportb(DataREG,Init374); // Đặt trở lại giá trị ban đầu cho 374. Latch374();

return(value); }

void WriteRAM(byte data) outportb(DataREG,ENBRAM); Latch374();

outportb(DataREG,data); WRITE();

outportb(DataREG,Init374); // Đặt trở lại giá trị ban đầu cho 374. Latch374();

}

/*===========================================*/ /*==Các chương trình con phục vụ cho chế độ chạy Debug==*/ /*===========================================*/

/*==Chương trình con khởi động Z80 ở chế độ DEBUG==*/ void GetToDebug(void)

{

outportb(DataREG,GetDebug); // Cho phép WAIT, cấm RAM, chờ đọc BUSY. Latch374();

outportb(CTRLREG,InitCTRL); }

/*==Chương trình con cho phép RAM sau khi xuất datadebug từ PC ra==*/ void EnableRAM(void)

{

outportb(DataREG,EnbRAM); Latch374();

}

/*==Chương trình con đọc trạng thái các thanh ghi==*/

byte ReadReg(byte LowAddr,byte HighAddr,byte RAddrLo,byte RAddrHi) { int countTx=0; int i,k; char Kytu; byte ErrorYes,BusyYes; byte FlagError=1;

/*Làm cho hết số lần CSROM định trước = TxNumber*/ do { countTx++; i=0; do { ErrorYes=RDError(); if ( ErrorYes ) break; delay(Set); i++;

/* if ( ( i==2 ) && ( ErrorYes == 0 ) ) { i=0; SetWAIT(); }; */ if ( ( i==10 ) && ( !RDError() ) ) { i=0; SetWAIT(); }; } while ( ErrorYes == 0 );

if ( ( countTx == 2 ) || ( countTx == 3 ) || ( countTx == 4 ) || ( countTx == 143) || ( countTx == 144) ) { outportb(CTRLREG,InitCTRL); delay(Set); }; if ( countTx == 4 ) EnableRAM(); for (k=1;k<=3;k++) { BusyYes=RDBusy();

if ((BusyYes)&&(k>=2)) break; // Đọc 2 lần để chống nhiễu. delay(Set); }; if ( BusyYes ) { switch ( countTx ) {

case 1: SetWAITDebug(JUMP); break; case 142: SetWAITDebug(JUMP); break; /*Các trường hợp read memory*/

39,43,44,45,49,50,51,56,57,58,64,65,66,69,70,71,77,78,79,82,83,84, 90,91,92,95,96,97,100,101,102,105,106,107,110,111,112,115,116,117, 120,121,122,127,128,129,136,137,138,139,143,144:

{

/*Nhảy về đầu chương trình nếu có lỗi*/ ErrorReg(LowAddr,HighAddr); return(0); } default: SetWAIT(); }; } /* Xử lý chu kỳ đọc/ghi bộ nhớ */ else { switch ( countTx ) {

case 2: SetWAITDebug(RAddrLo); break; case 3: SetWAITDebug(RAddrHi); break;

case 9: Kytu='A'; ReadRegister(Kytu); SetWAIT(); break; case 14: Kytu='B'; ReadRegister(Kytu); SetWAIT(); break; case 19: Kytu='C'; ReadRegister(Kytu); SetWAIT(); break; case 24: Kytu='D'; ReadRegister(Kytu); SetWAIT(); break; case 29: Kytu='E'; ReadRegister(Kytu); SetWAIT(); break; case 34: Kytu='H'; ReadRegister(Kytu); SetWAIT(); break; case 39: Kytu='L'; ReadRegister(Kytu); SetWAIT(); break; case 45: Kytu='I'; ReadRegister(Kytu); SetWAIT(); break; case 51: Kytu='R'; ReadRegister(Kytu); SetWAIT(); break; case 58: Kytu='F'; ReadRegister(Kytu); SetWAIT(); break; case 66: Kytu='X'; ReadRegister(Kytu); SetWAIT(); break; case 71: Kytu='x'; ReadRegister(Kytu); SetWAIT(); break; case 79: Kytu='Y'; ReadRegister(Kytu); SetWAIT(); break; case 84: Kytu='y'; ReadRegister(Kytu); SetWAIT(); break; case 92: Kytu='a'; ReadRegister(Kytu); SetWAIT(); break; case 97: Kytu='b'; ReadRegister(Kytu); SetWAIT(); break; case 102: Kytu='c'; ReadRegister(Kytu); SetWAIT(); break;

Một phần của tài liệu 20101005022225_lvmmt10 (Trang 86 - 135)

Tải bản đầy đủ (DOC)

(181 trang)
w