activegs-ios/kegs/Src/iwm.h

327 lines
8.5 KiB
C++

/*
ActiveGS, Copyright 2004-2016 Olivier Goguel, https://github.com/ogoguel/ActiveGS
Based on Kegs, Copyright 2004 Kent Dickey, https://kegs.sourceforge.net
This code is covered by the GNU GPL licence
*/
#pragma once
#ifdef INCLUDE_RCSID_C
const char rcsid_iwm_h[] = "@(#)$KmKId: iwm.h,v 1.14 2004-10-20 17:29:38-04 kentd Exp $";
#endif
#define MAX_TRACKS (2*80)
#define MAX_C7_DISKS 8
#define NIB_LEN_525 0x1900 /* 51072 bits per track */
#define NIBS_FROM_ADDR_TO_DATA 20
#define DSK_TYPE_PRODOS 0
#define DSK_TYPE_DOS33 1
#define DSK_TYPE_NIB 2
typedef struct _Disk Disk;
#ifdef _WIN32
#pragma pack(push,PRAGMA_PACK_SIZE)
#endif
STRUCT(Trk) {
Disk *dsk;
byte *nib_area;
int track_dirty;
int overflow_size;
int track_len;
int unix_pos;
int unix_len;
} XCODE_PRAGMA_PACK;
#define MAX_DISK_NAME 512
struct _Disk {
_ALIGNED(8) double dcycs_last_read;
char name_ptr[MAX_DISK_NAME];
char partition_name[MAX_DISK_NAME];
int partition_num;
int fd;
int force_size;
int image_start;
int image_size;
int smartport;
int disk_525;
int drive;
int cur_qtr_track;
int image_type;
int vol_num;
int write_prot;
int write_through_to_unix;
int disk_dirty;
int just_ejected;
int last_phase;
int nib_pos;
int num_tracks;
Trk *trks;
int slot;
int disk;
} XCODE_PRAGMA_PACK;
STRUCT(Iwm) {
Disk drive525[2];
Disk drive35[2];
Disk smartport[MAX_C7_DISKS];
int motor_on;
int motor_off;
int motor_off_vbl_count;
int motor_on35;
int head35;
int step_direction35;
int iwm_phase[4];
int iwm_mode;
int drive_select;
int q6;
int q7;
int enable2;
int reset;
word32 previous_write_val;
int previous_write_bits;
} XCODE_PRAGMA_PACK;
STRUCT(Driver_desc) {
word16 sig;
word16 blk_size;
word32 blk_count;
word16 dev_type;
word16 dev_id;
word32 data;
word16 drvr_count;
} XCODE_PRAGMA_PACK;
STRUCT(Part_map) {
word16 sig;
word16 sigpad;
word32 map_blk_cnt;
word32 phys_part_start;
word32 part_blk_cnt;
char part_name[32];
char part_type[32];
word32 data_start;
word32 data_cnt;
word32 part_status;
word32 log_boot_start;
word32 boot_size;
word32 boot_load;
word32 boot_load2;
word32 boot_entry;
word32 boot_entry2;
word32 boot_cksum;
char processor[16];
char junk[128];
} XCODE_PRAGMA_PACK;
class s_iwm : public serialized
{
public:
int g_fast_disk_emul ;
int g_slow_525_emul_wr ;
_ALIGNED(8) double g_dcycs_end_emul_wr ;
int g_fast_disk_unnib ;
int g_iwm_fake_fast ;
int from_disk_byte[256];
int from_disk_byte_valid ;
Iwm iwm;
int g_iwm_motor_on ;
int g_check_nibblization ;
int g_highest_smartport_unit ;
word32 g_cycs_in_io_read;
int g_cnt_enable2_handshake ;
s_iwm()
{
INIT_SERIALIZED();
g_fast_disk_emul = 1;
g_highest_smartport_unit = -1;
}
#define WRITE_TRK(X) \
if (X.trks) \
{ \
memcpy(ptr,X.trks,X.num_tracks * sizeof(Trk)); \
ptr += X.num_tracks * sizeof(Trk); \
for(int t=0;t<X.num_tracks;t++) \
{ \
if (X.trks[t].nib_area) \
{\
memcpy(ptr,X.trks[t].nib_area,X.trks[t].track_len);\
ptr+=X.trks[t].track_len;\
}\
}\
}
#define FREE_TRK(X) \
if (X.trks) \
{ \
for(int t=0;t<X.num_tracks;t++) \
{ \
if (X.trks[t].nib_area) \
{\
free(X.trks[t].nib_area); \
X.trks[t].nib_area=NULL; \
}\
}\
free(X.trks); \
X.trks=NULL; \
}
#define ALLOC_TRK(X) \
if (X.trks) \
{ \
X.trks = (Trk *)malloc(X.num_tracks * sizeof(Trk)); \
X.dcycs_last_read = get_dtime(); \
memcpy(X.trks,ptr,X.num_tracks * sizeof(Trk)); \
ptr += X.num_tracks * sizeof(Trk); \
for(int t=0;t<X.num_tracks;t++) \
{ \
X.trks[t].dsk = &X; \
if (X.trks[t].nib_area) \
{\
X.trks[t].nib_area = (byte*)malloc(X.trks[t].track_len);\
memcpy(X.trks[t].nib_area,ptr,X.trks[t].track_len);\
ptr+=X.trks[t].track_len;\
}\
}\
}
#define SIZE_TRK(X) \
if (X.trks) \
{ \
for(int t=0;t<X.num_tracks;t++)\
size += sizeof(Trk) + (X.trks[t].nib_area? X.trks[t].track_len : 0 ); \
}
#define SAVE_TRK_PTR(X,N) Trk* old_##N = X.trks; int old_fd_##N = X.fd; X.trks=NULL; X.fd=-1;
#define RESTORE_TRK_PTR(X,N) X.trks = old_##N; X.fd = old_fd_##N ;
void in(serialize* _s)
{
SAVE_TRK_PTR(iwm.drive525[0],drive5251);
SAVE_TRK_PTR(iwm.drive525[1],drive5252);
SAVE_TRK_PTR(iwm.drive35[0],drive351);
SAVE_TRK_PTR(iwm.drive35[1],drive352);
SAVE_TRK_PTR(iwm.smartport[0],smartport0);
SAVE_TRK_PTR(iwm.smartport[1],smartport1);
SAVE_TRK_PTR(iwm.smartport[2],smartport2);
SAVE_TRK_PTR(iwm.smartport[3],smartport3);
byte* ptr = (byte*)_s->data;
int ssize = *(int*)ptr;
if (ssize!= sizeof(*this))
ALIGNMENT_ERROR("iwm",ssize,sizeof(*this));
ptr += sizeof(ssize);
memcpy(this,ptr,sizeof(*this));
RESTORE_TRK_PTR(iwm.drive525[0],drive5251);
RESTORE_TRK_PTR(iwm.drive525[1],drive5252);
RESTORE_TRK_PTR(iwm.drive35[0],drive351);
RESTORE_TRK_PTR(iwm.drive35[1],drive352);
RESTORE_TRK_PTR(iwm.smartport[0],smartport0);
RESTORE_TRK_PTR(iwm.smartport[1],smartport1);
RESTORE_TRK_PTR(iwm.smartport[2],smartport2);
RESTORE_TRK_PTR(iwm.smartport[3],smartport3);
}
int out(serialize* _s, int _fastalloc)
{
// calcule la taille totale de la structure
SAVE_TRK_PTR(iwm.drive525[0],drive5251);
SAVE_TRK_PTR(iwm.drive525[1],drive5252);
SAVE_TRK_PTR(iwm.drive35[0],drive351);
SAVE_TRK_PTR(iwm.drive35[1],drive352);
SAVE_TRK_PTR(iwm.smartport[0],smartport0);
SAVE_TRK_PTR(iwm.smartport[1],smartport1);
SAVE_TRK_PTR(iwm.smartport[2],smartport2);
SAVE_TRK_PTR(iwm.smartport[3],smartport3);
// copie la structure de base
int ssize = sizeof(*this);
int size = ssize + sizeof(ssize);
_s->size = size;
_s->fastalloc = _fastalloc;
_s->data = (void*)x_malloc(size,_fastalloc);
byte* ptr = (byte*) _s->data;
memcpy(ptr,&ssize,sizeof(ssize));
ptr+=sizeof(ssize);
memcpy(ptr,this,sizeof(*this));
RESTORE_TRK_PTR(iwm.drive525[0],drive5251);
RESTORE_TRK_PTR(iwm.drive525[1],drive5252);
RESTORE_TRK_PTR(iwm.drive35[0],drive351);
RESTORE_TRK_PTR(iwm.drive35[1],drive352);
RESTORE_TRK_PTR(iwm.smartport[0],smartport0);
RESTORE_TRK_PTR(iwm.smartport[1],smartport1);
RESTORE_TRK_PTR(iwm.smartport[2],smartport2);
RESTORE_TRK_PTR(iwm.smartport[3],smartport3);
return size;
}
} XCODE_PRAGMA_PACK;
#ifdef _WIN32
#pragma pack(pop)
#endif
extern s_iwm g_iwm;
extern int g_track_bytes_35[];
extern int g_track_nibs_35[];
void iwm_init_drive(Disk *dsk, int smartport, int drive, int disk_525);
void disk_set_num_tracks(Disk *dsk, int num_tracks);
void iwm_init(void);
void iwm_shut(void); //OG
void iwm_reset(void);
void draw_iwm_status(int line, char *buf);
void iwm_flush_disk_to_unix(Disk *dsk);
void iwm_vbl_update(int doit_3_persec);
void iwm_show_stats(void);
void iwm_touch_switches(int loc, double dcycs);
void iwm_move_to_track(Disk *dsk, int new_track);
void iwm525_phase_change(int drive, int phase);
int iwm_read_status35(double dcycs);
void iwm_do_action35(double dcycs);
int iwm_read_c0ec(double dcycs);
int read_iwm(int loc, double dcycs);
void write_iwm(int loc, int val, double dcycs);
int iwm_read_enable2(double dcycs);
int iwm_read_enable2_handshake(double dcycs);
void iwm_write_enable2(int val, double dcycs);
int iwm_read_data(Disk *dsk, int fast_disk_emul, double dcycs);
void iwm_write_data(Disk *dsk, word32 val, int fast_disk_emul, double dcycs);
void sector_to_partial_nib(byte *in, byte *nib_ptr);
int disk_unnib_4x4(Disk *dsk);
int iwm_denib_track525(Disk *dsk, Trk *trk, int qtr_track, byte *outbuf);
int iwm_denib_track35(Disk *dsk, Trk *trk, int qtr_track, byte *outbuf);
int disk_track_to_unix(Disk *dsk, int qtr_track, byte *outbuf);
void show_hex_data(byte *buf, int count);
void disk_check_nibblization(Disk *dsk, int qtr_track, byte *buf, int size);
void disk_unix_to_nib(Disk *dsk, int qtr_track, int unix_pos, int unix_len, int nib_len);
void iwm_nibblize_track_nib525(Disk *dsk, Trk *trk, byte *track_buf, int qtr_track);
void iwm_nibblize_track_525(Disk *dsk, Trk *trk, byte *track_buf, int qtr_track);
void iwm_nibblize_track_35(Disk *dsk, Trk *trk, byte *track_buf, int qtr_track);
void disk_4x4_nib_out(Disk *dsk, word32 val);
void disk_nib_out(Disk *dsk, byte val, int size);
void disk_nib_end_track(Disk *dsk);
void iwm_show_track(int slot_drive, int track);
void iwm_show_a_track(Trk *trk);