I Y= X ?N
Chương V Chương trình nguoăn
5.1. Chương trình đưa data ra Ram chung, Debug, Dump, Run.
/*===================LUAƠN VAÍN TÔT NGHIEƠP===================== - Chương trình được viêt tređn Turbo C++ Version 3.0.
- Đeă tài: Giao tiêp giữa PC & KIT Z80 qua LPT1. - Giáo vieđn hướng dăn: Thaăy Nguyeên Xuađn Minh. - Người viêt: Lưu Đình Dũng.
- Ngày viêt: 11-03-1999.
- Caơp nhaơt laăn cuôi: 30-06-1999
- Chú ý: Dòng đaău tieđn cụa chương trình phại đượcc khai báo baỉng leơ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ư coơ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 đieău khieơ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 đoơ roơ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) { /*==============*/
/*==Phaă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; /*=================*/ /*==Phaăn chương trình==*/ /*=================*/
INIT(); // Khởi đoơng 374: Reset Z80, câm các CS. INIT8255(); // Khởi đoơng 8255: Mode 0, PA=PB=PC: Output. fp = fopen(Filename,"rb"); // Open Filename.bin.
CheckOk=Check(fp,Filenaae); // Kieơm tra file có hợp leơ khođng?. if (CheckOk==0) return(0);
/* Địa chư baĩt đaău load data ra RAM chung */ StartAddr.hi=0X00;
StartAddr.lo=0X00;
/* Hàm OutKIT trạ veă byte đ/c thâp + byte đ/c cao cụa phaăn baĩt đaă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 baĩt đaă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);
/* Baĩt đaă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 đeơ các port A,B,C trở thành ngõ vào */ Read8255();
Pseudo();
/*==============================*/ /*==Cháy ở chê đoơ Debug (LuaChon=1)==*/ /*==============================*/ if ( LuaChon==1 )
{
msg_toolbar(); // In thođ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 leơ. {
GetToDebug(); // Đưa Z80 vào chê đoơ WAIT (EWT='1'). clear_screen(0,20,80,4,MSG_ATTR);
msg_debug(); // In thođng báo.
do // (while key!=ESC) khi có tín hieơ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 hieơu ERROR. do {
ErrorYes=RDError(); // Đĩc tín hieơu ERROR. if ( ErrorYes ) break; // Nêu có -> thoát.
delay(Set); // Nêu khođng -> chờ 3 micro second. j++; /* Nêu chưa có ERROR thì CPU có theơ đ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 laăn đeơ chông nhieêu. delay(Set);
};
/* Nêu lúc này là chu kỳ M1 (BUSY=1) đaău tieđn thì: 1. Tiên hành đĩc tráng thái các thanh ghi
2. Kieơm tra đeơ nhạy tới breakpoint */ if ( (BusyYes) && (Flag_bp) )
{ /* Đĩc địa chư = PC đang được đưa vào RAM Đ/c này = đieơm thực hieơ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 leơnh này chưa thi hành đĩc t/ghi hoaịc đĩc roăi nhưng bị sai hoaịc trước đó khođ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 leơ ( là chu kỳ M1 thứ nhât ) */ if ( InvalidM1 )
{
CycleOld=CycleM1; CycleM1=FirstM1();
/* Đánh dâu chu kỳ M1 tiêp sau sẽ khođng hợp leơ */ if ( CycleM1==1 ) InvalidM1=0;
/* F8+CALL: SetWAIT() cho đên khi gaị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 hieơn leơnh hieơn tái laăn nào */ if ( AddrFlag == 0 )
{ do
{
AddrFlag = 1;
/* Đĩc địa chư = PC đang đượcc đưa vào RAM Đ/c này = đieơm t/hieơn JP HiAddrLoAddr */ LoAddr=RD_LoAddr();
HiAddr=RD_HiAddr();
delay(Set); // delay() roă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 hieơn sai leơ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 đeơ thực hieơn leơnh JP ADDR*/ do
{ //Đ/c JP veă ,đ/c JP đi (đố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, truyeăn đ/c HiAddr,LoAddr.
Tìm line có địa chư tương ứng, trạ veă line (CurrentLine). 2. Đ/c chuyeơ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 đã duyeơt qua roăi thì cho CPU cháy tiêp*/ else
{
AddrFlag=0; SetWAIT(); };
} // if ( ( BusyYes ) && (!Flag_bp) )
/* Nêu là chu kỳ đĩc boơ nhớ thì SetWAIT đeơ CPU cháy tiêp */ else SetWAIT();
} while ( Key != 27 );
/* Cháy tiêp sau khi thoát khỏi chê đoơ DEBUG */ GetToCont();
} // else if (Dia_chi==0) else // Báo loêi + break. {
error_debug(); return 0; }
} //end ( if LuaChon == 1 )
/*==============================*/ /*==Cháy ở chê đoơ normal (LuaChon=2)==*/ /*==============================*/ else if ( LuaChon==2 )
{
/*Khởi đoơng Z80 đeơ cháy chương trình từ RAM chung (normal mode)*/ GetToStart();
};
msg_finish();
/*Đốn chương trình dump boơ nhớ*/ do
{
Key=get_key();
while ( ( Key!=K_F3 ) && ( Key != K_ESC ) ) {
Key=get_key(); };
if (Key==K_F3) {
//Đ/c caăn dump: DStartLoAddr,DStartHiAddr,DEndLoAddr,DEndHiAddr GetToDebug(); //Cho phép WAIT, câm RAM, chờ đĩc BUSY
while (!InvalidFlag) { 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 leơ msgWait();
do
{ /*D/c jp veă D/c jp tới (đốn ct dump)*/
DumpError=Dump(AddrDump.lo,AddrDump.hi,TempAddr.lo,TempAddr.hi, DStartLoAddr,DStartHiAddr,DEndLoAddr,DEndHiAddr);
} while ( DumpError==0 ); /*đ/c đaău boơ nhớ, đ/c cuôi boơ nhớ*/ GetToCont();
InvalidFlag=0; }
} while (Key!=K_ESC); return 0; } /*===========================================================*/ /*==Các chương trình con=========================================*/ /*===========================================================*/ /*==Chương trình con phát ađ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 loê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 loê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 đoơng Z80 ở chê đoơ normal==*/ void GetToStart(void)
{
outportb(DataREG,GetStart); Latch374();
outportb(CTRLREG,InitCTRL); // Đaịt trở lái đường CTRL ở g.trị b.đaău }
/*==Chương trình khởi đoơng 8255: MODE 0, PA=PB=PC: input==*/ void Read8255(void)
{
outportb(DataREG,Init8255); // Chĩn 8255 Latch374();
outportb(DataREG,Mode0_In); // Ghi từ đ.khieơn WRITE();
outportb(DataREG,Init374); // Đaịt trở lái giá trị ban đaă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); // Đaịt trở lái đường CTRL ở g.trị b.đaău outportb(DataREG,RDPortC); // Đaịt trở lái giá trị ban đaău cho 374 Latch374();
/*Phat xung RD*/
outportb(CTRLREG,GENSTBLOW);
delay(Tgen); // Delay 3 micro second
outportb(CTRLREG,InitCTRL); // Đaịt trở lái đường CTRL ở g.trị b.đaău outportb(DataREG,Init374); // Đaịt trở lái giá trị ban đaău cho 374 Latch374();
}
/*==Chương trình con so sánh byte phát (DatOut) & byte thu (DAT)==*/ 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 đoơng KIT==*/ void INIT(void)
{
outportb(CTRLREG,InitCTRL); // Khởi táo các xung đieău khieơ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);
outportb(CTRLREG,InitCTRL); // Đaịt trở lái đường CTRL ở g.trị b.đaău }
/*==Chương trình khởi đoơng 8255: MODE 0, PA=PB=PC: output==*/ void INIT8255(void) { outportb(DataREG,Init8255); Latch374(); outportb(DataREG,Mode0_Out); WRITE();
outportb(DataREG,Init374); //Đaịt trở lái giá trị ban đaă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); //Đaịt trở lái giá trị ban đaă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); // Đaịt trở lái giá trị ban đaă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); // Đaịt trở lái đường CTRL ở giá trị ban đaă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); // Đaịt trở lái đường CTRL ở giá trị ban đaă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); // Đaịt trở lái giá trị ban đaău cho 374. Latch374();
return(value); }
/*==Chương trình con ghi RAM==*/ void WriteRAM(byte data)
outportb(DataREG,ENBRAM); Latch374();
outportb(DataREG,data); WRITE();
outportb(DataREG,Init374); // Đaịt trở lái giá trị ban đaău cho 374. Latch374();
}
/*===========================================*/ /*==Các chương trình con phúc vú cho chê đoơ cháy Debug==*/ /*===========================================*/
/*==Chương trình con khởi đoơng Z80 ở chê đoơ 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ô laă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 laăn đeơ chông nhieê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*/
case 2,3,7,8,9,12,13,14,17,18,19,22,23,24,27,28,29,32,33,34,37,38, 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 veă đaău chương trình nêu có loêi*/ ErrorReg(LowAddr,HighAddr); return(0); } default: SetWAIT(); }; }
/* Xử lý chu kỳ đĩc/ghi boơ 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;