Commit 98026234 authored by Sergio Costas's avatar Sergio Costas

Now the FAST_LOAD works 100% fine in all modes

parent 70938b91
......@@ -61,7 +61,6 @@ computer::computer() {
this->sound_bit = 0;
this->contended_zone = false;
this->no_contention = false;
this->cicles_counter=0;
this->interr = 0;
......@@ -124,7 +123,7 @@ void computer::emulate (int tstados) {
void computer::do_contention() {
if ((!this->contended_zone) || (this->no_contention)) {
if (!this->contended_zone) {
return;
}
......@@ -184,6 +183,14 @@ void ResetComputer () {
void Z80free_Wr (register word Addr, register byte Value) {
if ((Addr & 0xC000) == 0x4000) {
ordenador->do_contention();
}
ordenador->write_memory(Addr,Value);
}
void computer::write_memory (uint16_t Addr, uint8_t Value) {
switch (Addr & 0xC000) {
case 0x0000:
// only writes in the first 16K if we are in +3 mode and bit0 of mport2 is 1
......@@ -193,20 +200,19 @@ void Z80free_Wr (register word Addr, register byte Value) {
break;
case 0x4000:
ordenador->do_contention();
*(ordenador->block1 + Addr) = (unsigned char) Value;
break;
case 0x8000:
*(ordenador->block2 + Addr) = (unsigned char) Value;
break;
case 0xC000:
*(ordenador->block3 + Addr) = (unsigned char) Value;
break;
}
}
}
byte Z80free_Rd (register word Addr) {
......@@ -220,30 +226,35 @@ byte Z80free_Rd (register word Addr) {
break;
default:
switch (Addr & 0xC000) {
case 0x0000:
return ((byte) (*(ordenador->block0 + Addr)));
break;
case 0x4000:
if ((Addr & 0xC000) == 0x4000) {
ordenador->do_contention();
return ((byte) (*(ordenador->block1 + Addr)));
break;
}
return (ordenador->read_memory(Addr));
}
}
case 0x8000:
return ((byte) (*(ordenador->block2 + Addr)));
break;
uint8_t computer::read_memory(uint16_t Addr) {
switch (Addr & 0xC000) {
case 0x0000:
return ((byte) (*(ordenador->block0 + Addr)));
break;
case 0xC000:
return ((byte) (*(ordenador->block3 + Addr)));
break;
case 0x4000:
return ((byte) (*(ordenador->block1 + Addr)));
break;
default:
printf ("Memory error\n");
exit (1);
return 0;
}
break;
case 0x8000:
return ((byte) (*(ordenador->block2 + Addr)));
break;
case 0xC000:
return ((byte) (*(ordenador->block3 + Addr)));
break;
default:
printf ("Memory error\n");
exit (1);
return 0;
}
}
......
......@@ -49,7 +49,6 @@ public:
bool bw;
bool contended_zone; // 0-> no contention; 1-> contention possible
bool no_contention;
int cicles_counter; // counts how many pixel clock cicles passed since las interrupt
// Linux joystick private global variables
......@@ -97,6 +96,8 @@ public:
byte bus_empty();
void emulate(int);
void do_contention();
uint8_t read_memory(uint16_t Addr);
void write_memory (uint16_t Addr, uint8_t Value);
};
void fill_audio(void *udata,Uint8 *,int);
......
......@@ -36,7 +36,7 @@
#include "keyboard.hh"
#include "spk_ay.hh"
char debug_var=1;
bool debug_var = false;
Z80FREE procesador;
char salir;
......@@ -460,12 +460,11 @@ int main(int argc,char *argv[]) {
osd->set_message("Press F1 for help",4000);
printf("BPP: %d\n",llscreen->bpp);
debug_var = false;
while(salir) {
do {
ordenador->no_contention = false;
tstados=Z80free_ustep(&procesador);
ordenador->no_contention = true;
if(tstados<0) {
printf("Error %X\n",procesador.PC);
exit(1);
......@@ -473,11 +472,11 @@ int main(int argc,char *argv[]) {
ordenador->emulate(tstados); // execute the whole hardware emulation for that number of TSTATES
} while(procesador.Status!=Z80XX);
PC=procesador.PC;
/* if PC is 0x0556, a call to LD_BYTES has been made, so if
FAST_LOAD is 1, we must load the block in memory and return */
if((!microdrive->mdr_paged) && (PC==0x0556) && (ordenador->tape_fast_load)) {
if((!microdrive->mdr_paged) && (PC==0x0556) && (ordenador->tape_fast_load) && (ordenador->page48k == 1)) {
if(ordenador->current_tap != "") {
//procesador.Rm.br.F &= ~F_Z;
do_fast_load();
......@@ -490,7 +489,7 @@ int main(int argc,char *argv[]) {
/* if PC is 0x04C2, a call to SA_BYTES has been made, so if
we want to save to the TAP file, we do it */
if((!microdrive->mdr_paged) && (PC==0x04C2) && (ordenador->tape_write==1)) {
if((!microdrive->mdr_paged) && (PC==0x04C2) && (ordenador->tape_write==1) && (ordenador->page48k == 1)) {
uint8_t *data;
uint8_t op_xor;
......@@ -498,6 +497,8 @@ int main(int argc,char *argv[]) {
uint32_t length;
int pointer;
do_push(0x053F); // return address
length = (uint32_t)(procesador.Rm.wr.DE);
length += 2;
......@@ -512,7 +513,7 @@ int main(int argc,char *argv[]) {
if (procesador.Rm.wr.DE == 0)
salir = 2;
if (!salir) {
dato = Z80free_Rd(procesador.Rm.wr.IX); // read data
dato = ordenador->read_memory(procesador.Rm.wr.IX); // read data
op_xor^=dato;
data[pointer++] = dato;
procesador.Rm.wr.IX++;
......@@ -559,9 +560,28 @@ int main(int argc,char *argv[]) {
return 0;
}
void print_status() {
printf("\nPC: 0x%04X SP:0x%04X\n",procesador.PC,procesador.Rm.wr.SP);
printf("AF: 0x%04X BC: 0x%04X DE: 0x%04X HL: 0x%04X\n",procesador.Rm.wr.AF,procesador.Rm.wr.BC,procesador.Rm.wr.DE,procesador.Rm.wr.HL);
printf("AF': 0x%04X BC': 0x%04X DE': 0x%04X HL': 0x%04X\n",procesador.Ra.wr.AF,procesador.Ra.wr.BC,procesador.Ra.wr.DE,procesador.Ra.wr.HL);
printf("IX: 0x%04X IY: 0x%04X IX': 0x%04X IY': 0x%04X\n",procesador.Rm.wr.IX,procesador.Rm.wr.IY,procesador.Ra.wr.IX,procesador.Ra.wr.IY);
printf("IFF1: %X IFF2: %X I: %X R: %X\n\n\n",procesador.IFF1,procesador.IFF2,procesador.I,procesador.R|procesador.R2);
}
void do_push(uint16_t value) {
procesador.Rm.wr.SP -= 2;
ordenador->write_memory(procesador.Rm.wr.SP, (uint8_t)(value & 0xFF));
value >>= 8;
ordenador->write_memory(procesador.Rm.wr.SP + 1, (uint8_t)(value & 0xFF));
}
void do_fast_load() {
if (!(procesador.Rm.br.F & F_C)) { // if Carry=0, is VERIFY, so return OK
do_push(0x053F);
procesador.Rm.br.F |= F_C; // verify OK
procesador.Rm.wr.IX += procesador.Rm.wr.DE;
procesador.Rm.wr.DE = 0;
......@@ -583,6 +603,7 @@ void do_fast_load() {
procesador.Rm.wr.IX += procesador.Rm.wr.DE;
procesador.Rm.wr.DE = 0;
osd->set_message("No tape selected",2000);
do_push(0x053F);
ordenador->other_ret = 1; // next instruction must be RET
return;
break;
......@@ -598,6 +619,7 @@ void do_fast_load() {
procesador.Rm.wr.IX += procesador.Rm.wr.DE;
procesador.Rm.wr.DE = 0;
osd->set_message("End of tape. Rewind it.",2000);
do_push(0x053F);
ordenador->other_ret = 1; // next instruction must be RET
return;
case FASTLOAD_OK:
......@@ -606,21 +628,27 @@ void do_fast_load() {
if ((size == 0) || (procesador.Rm.wr.DE == 0)) {
break;
}
Z80free_Wr (procesador.Rm.wr.IX, (byte) data[counter]); // store the byte
ordenador->write_memory(procesador.Rm.wr.IX, (byte) data[counter]); // store the byte
procesador.Rm.wr.IX++;
procesador.Rm.wr.DE--;
counter++;
size--;
}
procesador.Rm.wr.AF = 0x0093;
procesador.Rm.br.H = 0;
procesador.Ra.wr.AF = 0x0145;
procesador.Rm.wr.BC = 0xB001;
procesador.IFF1 = 0;
procesador.IFF2 = 0;
ordenador->other_ret = 1; // next instruction must be RET
do_push(0x053F);
if (size == 0) {
if (procesador.Rm.wr.DE == 0) {
procesador.Rm.br.F |= (F_C); // Load OK
ordenador->other_ret = 1; // next instruction must be RET
return;
}
}
procesador.Rm.br.F &= (~F_C); // Load error
ordenador->other_ret = 1; // next instruction must be RET
return;
break;
case FASTLOAD_NO_FLAG:
......
......@@ -17,6 +17,8 @@
*
*/
#include <inttypes.h>
#include "z80free/Z80free.h"
#include "osd.hh"
#include "screen.hh"
......@@ -26,7 +28,7 @@
#define NUM_SNDBUF 2
extern char debug_var;
extern bool debug_var;
extern Z80FREE procesador;
extern char path_snaps[2049];
......@@ -37,5 +39,7 @@ extern unsigned int jump_frames,curr_frames;
void load_rom(char);
void load_main_game(const char *nombre);
void do_fast_load();
void print_status();
void do_push(uint16_t value);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment