Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Alex Badea (8):
- upd_fdc: implement Terminal Count support
- debugger: add support for setting IM and IFFs
- gtk debugger: use MEMORY_PAGE_SIZE instead of hard-coded 4k
- disk: allow reading mgt layouts of 80x16x256 and 40x16x256
- HACK disk: disable size checking when writing .mgt images
- HACK disk: add a bunch of fprintf() debug logging
- memory: change page size from 4k to 1k
- HACK if1: add HC uPD disk interface support
- fuse/debugger/command.c | 18 +++
- fuse/debugger/commandl.l | 3 +
- fuse/memory.h | 2 +-
- fuse/peripherals/disk/disk.c | 11 +-
- fuse/peripherals/disk/fdd.c | 1 +
- fuse/peripherals/disk/upd_fdc.c | 84 ++++++++++---
- fuse/peripherals/disk/upd_fdc.h | 2 +
- fuse/peripherals/if1.c | 250 ++++++++++++++++++++++++++++++++++++++-
- fuse/ui/gtk/debugger.c | 2 +-
- 9 files changed, 349 insertions(+), 24 deletions(-)
- parent 88be0872bb7a7a30c7697ccd0da8add02c859f79
- Fix regression in GTK UI pause menu from r4685 (bug #3523741) (Sergio).
- git-svn-id: https://fuse-emulator.svn.sourceforge.net/svnroot/fuse-emulator/trunk@4701 6c7d1b9a-d430-0410-8293-a2b96dacb39b
- commit b025baa9e4e91ab1309e9904ee2424f7e30531a5
- Author: Alex Badea <abadea@ixiacom.com>
- Date: Wed May 23 18:59:51 2012 +0300
- upd_fdc: implement Terminal Count support
- Add an API which allows signalling of the TC input to the FDC. If TC
- is asserted, store this in a flag and use it to disable sending further
- result data for reads, or to fill in zeroes for writes. Also disable
- setting end-of-cylinder if TC is asserted.
- Since the host usually asserts TC after reading/write the last data byte
- to/from the data port, the start_{read,write}* functions are deferred
- to an event, instead of being called directly from port I/O. This gives
- the host some time to assert TC.
- ---
- fuse/peripherals/disk/upd_fdc.c | 44 +++++++++++++++++++++++++++------------
- fuse/peripherals/disk/upd_fdc.h | 2 ++
- 2 files changed, 33 insertions(+), 13 deletions(-)
- diff --git a/fuse/peripherals/disk/upd_fdc.c b/fuse/peripherals/disk/upd_fdc.c
- index 253bc10..ca6db57 100644
- --- a/fuse/peripherals/disk/upd_fdc.c
- +++ b/fuse/peripherals/disk/upd_fdc.c
- @@ -117,6 +117,7 @@ cmd_identify( upd_fdc *f )
- break;
- r++;
- }
- + f->tc = 0;
- f->mt = f->command_register >> 7; /* Multi track READ/WRITE */
- f->mf = ( f->command_register >> 6 ) & 0x01; /* MFM format */
- f->sk = ( f->command_register >> 5 ) & 0x01; /* Skip DELETED/NONDELETED sectors */
- @@ -148,6 +149,7 @@ upd_fdc_master_reset( upd_fdc *f )
- f->cycle = 0;
- f->last_sector_read = 0;
- f->read_id = 0;
- + f->tc = 0;
- /* preserve disabled state of speedlock_hack */
- if( f->speedlock != -1 ) f->speedlock = 0;
- }
- @@ -571,7 +573,7 @@ start_read_data( upd_fdc *f )
- skip_deleted_sector:
- multi_track_next:
- if( f->first_rw || f->read_id ||
- - f->data_register[5] > f->data_register[3] ) {
- + (!f->tc && f->data_register[5] > f->data_register[3]) ) {
- if( !f->read_id ) {
- if( !f->first_rw )
- f->data_register[3]++;
- @@ -630,7 +632,7 @@ abort_read_data:
- * 3. terminal count is not received
- * note: in +3 uPD765 never got TC
- */
- - if( !f->status_register[0] && !f->status_register[1] ) {
- + if( !f->status_register[0] && !f->status_register[1] && !f->tc ) {
- f->status_register[0] |= UPD_FDC_ST0_INT_ABNORM;
- f->status_register[1] |= UPD_FDC_ST1_EOF_CYLINDER;
- }
- @@ -664,7 +666,7 @@ start_write_data( upd_fdc *f )
- multi_track_next:
- if( f->first_rw || f->read_id ||
- - f->data_register[5] > f->data_register[3] ) {
- + (!f->tc && f->data_register[5] > f->data_register[3]) ) {
- if( !f->read_id ) {
- if( !f->first_rw )
- f->data_register[3]++;
- @@ -731,8 +733,10 @@ abort_write_data:
- * 3. terminal count is not received
- * note: in +3 uPD765 never got TC
- */
- - f->status_register[0] |= UPD_FDC_ST0_INT_ABNORM;
- - f->status_register[1] |= UPD_FDC_ST1_EOF_CYLINDER;
- + if( !f->tc ) {
- + f->status_register[0] |= UPD_FDC_ST0_INT_ABNORM;
- + f->status_register[1] |= UPD_FDC_ST1_EOF_CYLINDER;
- + }
- f->main_status &= ~UPD_FDC_MAIN_EXECUTION;
- f->intrq = UPD_INTRQ_RESULT;
- cmd_result( f );
- @@ -747,6 +751,14 @@ abort_write_data:
- }
- static void
- +start_readwrite_data_later( upd_fdc *f )
- +{
- + event_add_with_data( tstates +
- + machine_current->timings.processor_speed / 1000,
- + fdc_event, f );
- +}
- +
- +static void
- start_write_id( upd_fdc *f )
- {
- int i;
- @@ -894,7 +906,7 @@ upd_fdc_read_data( upd_fdc *f )
- /* EOSpeedlock hack */
- r = d->fdd.data & 0xff;
- - if( f->data_offset == f->rlen ) { /* send only rlen byte to host */
- + if( f->data_offset == f->rlen || f->tc ) { /* send only rlen byte to host */
- while( f->data_offset < f->sector_length ) {
- fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
- f->data_offset++;
- @@ -916,14 +928,14 @@ upd_fdc_read_data( upd_fdc *f )
- if( f->cmd->id == UPD_CMD_READ_DATA ) {
- if( f->ddam != f->del_data ) { /* we read a not 'wanted' sector... so */
- - if( f->data_register[5] > f->data_register[3] ) /* if we want to read more... */
- + if( !f->tc && f->data_register[5] > f->data_register[3] ) /* if we want to read more... */
- f->status_register[0] |= UPD_FDC_ST0_INT_ABNORM;
- cmd_result( f ); /* set up result phase */
- return r;
- }
- f->rev = 2;
- f->main_status &= ~UPD_FDC_MAIN_DATAREQ;
- - start_read_data( f );
- + start_readwrite_data_later( f );
- } else { /* READ DIAG */
- f->data_register[3]++; /*FIXME ??? */
- f->data_register[5]--;
- @@ -932,7 +944,7 @@ upd_fdc_read_data( upd_fdc *f )
- return r;
- }
- f->main_status &= ~UPD_FDC_MAIN_DATAREQ;
- - start_read_diag( f );
- + start_readwrite_data_later( f );
- }
- }
- return r;
- @@ -1063,7 +1075,7 @@ upd_fdc_write_data( upd_fdc *f, libspectrum_byte data )
- d->fdd.data = data;
- fdd_read_write_data( &d->fdd, FDD_WRITE ); crc_add( f, d );
- - if( f->data_offset == f->rlen ) { /* read only rlen byte from host */
- + if( f->data_offset == f->rlen || f->tc ) { /* read only rlen byte from host */
- d->fdd.data = 0x00;
- while( f->data_offset < f->sector_length ) { /* fill with 0x00 */
- fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
- @@ -1076,7 +1088,7 @@ upd_fdc_write_data( upd_fdc *f, libspectrum_byte data )
- d->fdd.data = f->crc & 0xff;
- fdd_read_write_data( &d->fdd, FDD_WRITE ); /* write crc2 */
- f->main_status &= ~UPD_FDC_MAIN_DATAREQ;
- - start_write_data( f );
- + start_readwrite_data_later( f );
- }
- return;
- } else { /* SCAN */
- @@ -1104,7 +1116,7 @@ upd_fdc_write_data( upd_fdc *f, libspectrum_byte data )
- f->data_register[3] += f->data_register[7]; /*FIXME what about STP>2 or STP<1 */
- if( f->ddam != f->del_data ) { /* we read a not 'wanted' sector... so */
- - if( f->data_register[5] >= f->data_register[3] ) /* if we want to read more... */
- + if( !f->tc && f->data_register[5] >= f->data_register[3] ) /* if we want to read more... */
- f->status_register[0] |= UPD_FDC_ST0_INT_ABNORM;
- cmd_result( f ); /* set up result phase */
- return;
- @@ -1116,7 +1128,7 @@ upd_fdc_write_data( upd_fdc *f, libspectrum_byte data )
- }
- f->rev = 2;
- f->main_status &= ~UPD_FDC_MAIN_DATAREQ;
- - start_read_data( f );
- + start_readwrite_data_later( f );
- }
- return;
- }
- @@ -1345,3 +1357,9 @@ upd_fdc_write_data( upd_fdc *f, libspectrum_byte data )
- f->cycle++;
- }
- }
- +
- +void upd_fdc_tc( upd_fdc *f, int tc )
- +{
- + if (tc > 0)
- + f->tc = 1;
- +}
- diff --git a/fuse/peripherals/disk/upd_fdc.h b/fuse/peripherals/disk/upd_fdc.h
- index c5ba2aa..400dd38 100644
- --- a/fuse/peripherals/disk/upd_fdc.h
- +++ b/fuse/peripherals/disk/upd_fdc.h
- @@ -139,6 +139,7 @@ typedef struct upd_fdc {
- int cycle; /* read/write cycle num */
- int del_data; /* READ/WRITE deleted data */
- int mt; /* multitrack operations */
- + int tc; /* Terminal Count asserted */
- int mf; /* MFM mode */
- int sk; /* skip deleted/not deleted data */
- int hd; /* physical head address */
- @@ -173,6 +174,7 @@ void upd_fdc_init_events( void );
- /* allocate an fdc */
- upd_fdc *upd_fdc_alloc_fdc( upd_type_t type, upd_clock_t clock );
- void upd_fdc_master_reset( upd_fdc *f );
- +void upd_fdc_tc( upd_fdc *f, int tc );
- libspectrum_byte upd_fdc_read_status( upd_fdc *f );
- commit 19f9c35c74649388ec5254dd501e6f0d90c97eb9
- Author: Alex Badea <abadea@ixiacom.com>
- Date: Fri Jun 22 12:53:49 2012 +0300
- debugger: add support for setting IM and IFFs
- ---
- fuse/debugger/command.c | 18 ++++++++++++++++++
- fuse/debugger/commandl.l | 3 +++
- 2 files changed, 21 insertions(+)
- diff --git a/fuse/debugger/command.c b/fuse/debugger/command.c
- index 2be43b0..28d8429 100644
- --- a/fuse/debugger/command.c
- +++ b/fuse/debugger/command.c
- @@ -130,6 +130,9 @@ debugger_register_hash( const char *name )
- case 0x7063: /* PC */
- case 0x6978: /* IX */
- case 0x6979: /* IY */
- + case 0x696d: /* IM */
- + case 0x69666631: /* IFF1 */
- + case 0x69666632: /* IFF2 */
- return hash;
- default: return -1;
- @@ -184,6 +187,11 @@ debugger_register_get( int which )
- case 0x6978: return IX;
- case 0x6979: return IY;
- + /* interrupt flags */
- + case 0x696d: return IM;
- + case 0x69666631: return IFF1;
- + case 0x69666632: return IFF2;
- +
- default:
- ui_error( UI_ERROR_ERROR, "attempt to get unknown register '%d'", which );
- return 0;
- @@ -229,6 +237,11 @@ debugger_register_set( int which, libspectrum_word value )
- case 0x6978: IX = value; break;
- case 0x6979: IY = value; break;
- + /* interrupt flags */
- + case 0x696d: IM = value; break;
- + case 0x69666631: IFF1 = value; break;
- + case 0x69666632: IFF2 = value; break;
- +
- default:
- ui_error( UI_ERROR_ERROR, "attempt to set unknown register '%d'", which );
- break;
- @@ -274,6 +287,11 @@ debugger_register_text( int which )
- case 0x6978: return "IX";
- case 0x6979: return "IY";
- + /* interrupt flags */
- + case 0x696d: return "IM";
- + case 0x69666631: return "IFF1";
- + case 0x69666632: return "IFF2";
- +
- default:
- ui_error( UI_ERROR_ERROR, "attempt to get unknown register '%d'", which );
- return "(invalid)";
- diff --git a/fuse/debugger/commandl.l b/fuse/debugger/commandl.l
- index 0439df9..a07268e 100644
- --- a/fuse/debugger/commandl.l
- +++ b/fuse/debugger/commandl.l
- @@ -96,6 +96,9 @@ af|bc|de|hl|"af\'"|"bc\'"|"de\'"|"hl\'" {
- sp|pc|ix|iy { yylval.reg = debugger_register_hash( yytext );
- return DEBUGGER_REGISTER; }
- +im|iff1|iff2 { yylval.reg = debugger_register_hash( yytext );
- + return DEBUGGER_REGISTER; }
- +
- "(" { return '('; }
- ")" { return ')'; }
- commit 1debab6dcfe96ca20d2a5251bcca4854125a8c88
- Author: Alex Badea <abadea@ixiacom.com>
- Date: Fri Jun 22 12:54:52 2012 +0300
- gtk debugger: use MEMORY_PAGE_SIZE instead of hard-coded 4k
- This fixes values displayed in the Memory Map.
- ---
- fuse/ui/gtk/debugger.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
- diff --git a/fuse/ui/gtk/debugger.c b/fuse/ui/gtk/debugger.c
- index cbc2d30..86815a9 100644
- --- a/fuse/ui/gtk/debugger.c
- +++ b/fuse/ui/gtk/debugger.c
- @@ -823,7 +823,7 @@ update_memory_map( void )
- char buffer[40];
- GtkWidget **row_labels = map_label[row];
- - snprintf( buffer, 40, format_16_bit(), (unsigned)block * 0x1000 );
- + snprintf( buffer, 40, format_16_bit(), (unsigned)block * MEMORY_PAGE_SIZE );
- row_labels[0] = gtk_label_new( buffer );
- snprintf( buffer, 40, "%s %d",
- commit 539e3476ff3ae32608fd13d3ed902bae99660c3d
- Author: Alex Badea <abadea@ixiacom.com>
- Date: Fri Jun 22 12:55:49 2012 +0300
- disk: allow reading mgt layouts of 80x16x256 and 40x16x256
- ---
- fuse/peripherals/disk/disk.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
- diff --git a/fuse/peripherals/disk/disk.c b/fuse/peripherals/disk/disk.c
- index f8aa264..451bc6e 100644
- --- a/fuse/peripherals/disk/disk.c
- +++ b/fuse/peripherals/disk/disk.c
- @@ -1100,7 +1100,11 @@ open_img_mgt_opd( buffer_t *buffer, disk_t *d )
- * 2*80*10*512, 1*80*10*512, 1*40*10*512, 1*40*18*256, 1*80*18*256,
- * 2*80*18*256
- */
- - if( buffer->file.length == 2*80*10*512 ) {
- + if( buffer->file.length == 2*80*16*256 ) {
- + d->sides = 2; d->cylinders = 80; sectors = 16; seclen = 256;
- + } else if( buffer->file.length == 2*40*16*256 ) {
- + d->sides = 2; d->cylinders = 40; sectors = 16; seclen = 256;
- + } else if( buffer->file.length == 2*80*10*512 ) {
- d->sides = 2; d->cylinders = 80; sectors = 10; seclen = 512;
- } else if( buffer->file.length == 1*80*10*512 ) {
- /* we cannot distinguish between a single sided 80 track image
- commit f90555b0aad4ccbf248bd1f3708d5d4648314457
- Author: Alex Badea <abadea@ixiacom.com>
- Date: Fri Jun 22 12:56:48 2012 +0300
- HACK disk: disable size checking when writing .mgt images
- We use 80x16x256 and 40x16x256. We should add these to the supported
- layouts instead of entirely disabling checking.
- ---
- fuse/peripherals/disk/disk.c | 5 +++++
- 1 file changed, 5 insertions(+)
- diff --git a/fuse/peripherals/disk/disk.c b/fuse/peripherals/disk/disk.c
- index 451bc6e..67b71a5 100644
- --- a/fuse/peripherals/disk/disk.c
- +++ b/fuse/peripherals/disk/disk.c
- @@ -2128,10 +2128,15 @@ write_img_mgt_opd( FILE *file, disk_t *d )
- {
- int i, j, sbase, sectors, seclen, mfm, cyl;
- + check_disk_geom( d, &sbase, §ors, &seclen, &mfm, &cyl );
- + fprintf(stderr, "%s: sbase=%d sectors=%d seclen=%d cyl=%d\n", __func__, sbase, sectors, seclen, cyl);
- +
- +/*
- if( check_disk_geom( d, &sbase, §ors, &seclen, &mfm, &cyl ) ||
- ( d->type != DISK_OPD && ( sbase != 1 || seclen != 2 || sectors != 10 ) ) ||
- ( d->type == DISK_OPD && ( sbase != 0 || seclen != 1 || sectors != 18 ) ) )
- return d->status = DISK_GEOM;
- +*/
- if( cyl == -1 ) cyl = d->cylinders;
- if( cyl != 40 && cyl != 80 )
- commit 064504f340231034327dcf6be137b23205fcced7
- Author: Alex Badea <abadea@ixiacom.com>
- Date: Fri Jun 22 12:59:24 2012 +0300
- HACK disk: add a bunch of fprintf() debug logging
- ---
- fuse/peripherals/disk/fdd.c | 1 +
- fuse/peripherals/disk/upd_fdc.c | 40 +++++++++++++++++++++++++++++++++++++--
- 2 files changed, 39 insertions(+), 2 deletions(-)
- diff --git a/fuse/peripherals/disk/fdd.c b/fuse/peripherals/disk/fdd.c
- index 878019d..7ee37fb 100644
- --- a/fuse/peripherals/disk/fdd.c
- +++ b/fuse/peripherals/disk/fdd.c
- @@ -209,6 +209,7 @@ fdd_head_load( fdd_t *d, int load )
- void
- fdd_select( fdd_t *d, int select )
- {
- +fprintf(stderr, "%s: fdd=%p select=%d\n", __func__, d, select); // XXX
- d->selected = select > 0 ? 1 : 0;
- /*
- ... Drive Select when activated to a logical
- diff --git a/fuse/peripherals/disk/upd_fdc.c b/fuse/peripherals/disk/upd_fdc.c
- index ca6db57..0839a33 100644
- --- a/fuse/peripherals/disk/upd_fdc.c
- +++ b/fuse/peripherals/disk/upd_fdc.c
- @@ -264,6 +264,7 @@ read_datamark( upd_fdc *f )
- if( d->fdd.data == 0x00 ) /* go to PLL sync */
- break;
- +fprintf(stderr, "%s:%d: data 0x%02x\n", __func__, __LINE__, d->fdd.data);
- f->status_register[2] |= UPD_FDC_ST2_MISSING_DM;
- return 1; /* something wrong... */
- }
- @@ -276,18 +277,21 @@ read_datamark( upd_fdc *f )
- if( d->fdd.data == 0xffa1 ) /* got to a1 mark */
- break;
- +fprintf(stderr, "%s:%d: data 0x%02x\n", __func__, __LINE__, d->fdd.data);
- f->status_register[2] |= UPD_FDC_ST2_MISSING_DM;
- return 1;
- }
- for( i = d->fdd.data == 0xffa1 ? 2 : 3; i > 0; i-- ) {
- fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
- if( d->fdd.data != 0xffa1 ) {
- +fprintf(stderr, "%s:%d: data 0x%02x\n", __func__, __LINE__, d->fdd.data);
- f->status_register[2] |= UPD_FDC_ST2_MISSING_DM;
- return 1;
- }
- }
- fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
- if( d->fdd.data < 0x00f8 || d->fdd.data > 0x00fb ) { /* !fb deleted mark */
- +fprintf(stderr, "%s:%d: data 0x%02x\n", __func__, __LINE__, d->fdd.data);
- f->status_register[2] |= UPD_FDC_ST2_MISSING_DM;
- return 1;
- }
- @@ -305,6 +309,7 @@ read_datamark( upd_fdc *f )
- if( d->fdd.data == 0x00 ) /* go to PLL sync */
- break;
- +fprintf(stderr, "%s:%d: data 0x%02x\n", __func__, __LINE__, d->fdd.data);
- f->status_register[2] |= UPD_FDC_ST2_MISSING_DM;
- return 1; /* something wrong... */
- }
- @@ -317,12 +322,14 @@ read_datamark( upd_fdc *f )
- if( d->fdd.data >= 0xfff8 && d->fdd.data <= 0xfffb ) /* !fb deleted mark */
- break;
- +fprintf(stderr, "%s:%d: data 0x%02x\n", __func__, __LINE__, d->fdd.data);
- f->status_register[2] |= UPD_FDC_ST2_MISSING_DM;
- return 1;
- }
- if( i == 0 ) {
- fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d );
- if( d->fdd.data < 0xfff8 || d->fdd.data > 0xfffb ) { /* !fb deleted mark */
- +fprintf(stderr, "%s:%d: data 0x%02x\n", __func__, __LINE__, d->fdd.data);
- f->status_register[2] |= UPD_FDC_ST2_MISSING_DM;
- return 1;
- }
- @@ -333,6 +340,7 @@ read_datamark( upd_fdc *f )
- f->ddam = 0;
- return 0;
- }
- +fprintf(stderr, "%s:%d: data 0x%02x\n", __func__, __LINE__, d->fdd.data);
- f->status_register[2] |= UPD_FDC_ST2_MISSING_DM;
- return 1;
- }
- @@ -399,6 +407,17 @@ upd_fdc_alloc_fdc( upd_type_t type, upd_clock_t clock )
- static void
- cmd_result( upd_fdc *f )
- {
- +fprintf(stderr, "%s: cmd 0x%x, status: %02x %02x %02x, data %02x %02x %02x %02x %02x\n",
- + __func__, f->cmd->value,
- + f->status_register[0],
- + f->status_register[1],
- + f->status_register[2],
- + f->data_register[0],
- + f->data_register[1],
- + f->data_register[2],
- + f->data_register[3],
- + f->data_register[4]);
- +
- f->cycle = f->cmd->res_length;
- f->main_status &= ~UPD_FDC_MAIN_EXECUTION;
- f->main_status |= UPD_FDC_MAIN_DATAREQ;
- @@ -572,6 +591,7 @@ start_read_data( upd_fdc *f )
- int i;
- skip_deleted_sector:
- multi_track_next:
- +fprintf(stderr, "%s: start (tc=%d)\n", __func__, f->tc);
- if( f->first_rw || f->read_id ||
- (!f->tc && f->data_register[5] > f->data_register[3]) ) {
- if( !f->read_id ) {
- @@ -617,6 +637,7 @@ multi_track_next:
- }
- }
- } else {
- +fprintf(stderr, "%s: check (mt=%d tc=%d)\n", __func__, f->mt, f->tc);
- if( f->mt ) {
- f->data_register[1]++; /* next track */
- f->data_register[3] = 1; /* first sector */
- @@ -630,7 +651,7 @@ abort_read_data:
- * (i.e. no other errors occur like no data.
- * 2. sector being read is same specified by EOT
- * 3. terminal count is not received
- -* note: in +3 uPD765 never got TC
- +* note: in +3 uPD765 never got TC (FIXME)
- */
- if( !f->status_register[0] && !f->status_register[1] && !f->tc ) {
- f->status_register[0] |= UPD_FDC_ST0_INT_ABNORM;
- @@ -648,6 +669,7 @@ abort_read_data:
- cmd_result( f );
- return;
- }
- +
- f->main_status |= UPD_FDC_MAIN_DATAREQ;
- if( f->cmd->id != UPD_CMD_SCAN )
- f->main_status |= UPD_FDC_MAIN_DATA_READ;
- @@ -731,7 +753,7 @@ abort_write_data:
- * (i.e. no other errors occur like no data.
- * 2. sector being read is same specified by EOT
- * 3. terminal count is not received
- -* note: in +3 uPD765 never got TC
- +* note: in +3 uPD765 never got TC (FIXME)
- */
- if( !f->tc ) {
- f->status_register[0] |= UPD_FDC_ST0_INT_ABNORM;
- @@ -890,6 +912,7 @@ upd_fdc_read_data( upd_fdc *f )
- return 0xff;
- if( f->state == UPD_FDC_STATE_EXE ) { /* READ_DATA/READ_DIAG */
- +
- f->data_offset++; /* count read bytes */
- fdd_read_write_data( &d->fdd, FDD_READ ); crc_add( f, d ); /* read a byte */
- @@ -1157,6 +1180,15 @@ upd_fdc_write_data( upd_fdc *f, libspectrum_byte data )
- f->data_register[f->cycle - 1] = data; /* store data register bytes */
- }
- if( f->cycle >= f->cmd->cmd_length ) { /* we already read all neccessery byte */
- +fprintf(stderr, "%s: cmd 0x%02x data %02x %02x %02x %02x %02x %02x %02x %02x\n", __func__, f->cmd->value,
- + f->data_register[0],
- + f->data_register[1],
- + f->data_register[2],
- + f->data_register[3],
- + f->data_register[4],
- + f->data_register[5],
- + f->data_register[6],
- + f->data_register[7]);
- f->state = UPD_FDC_STATE_EXE; /* start execution of the command */
- f->main_status &= ~UPD_FDC_MAIN_DATAREQ;
- if( f->non_dma ) { /* btw: only NON-DMA mode emulated */
- @@ -1358,8 +1390,12 @@ upd_fdc_write_data( upd_fdc *f, libspectrum_byte data )
- }
- }
- +/* Signal the state of the Terminal Count input. */
- void upd_fdc_tc( upd_fdc *f, int tc )
- {
- +fprintf(stderr, "%s: tc=%d data_offset=%d rlen=%d status: %02x %02x\n", __func__,
- + tc, f->data_offset, f->rlen, f->status_register[0], f->status_register[1]);
- +
- if (tc > 0)
- f->tc = 1;
- }
- commit 09637da45885114a5d250b361c4eb60470850003
- Author: Alex Badea <abadea@ixiacom.com>
- Date: Fri Jun 22 13:00:15 2012 +0300
- memory: change page size from 4k to 1k
- The HC Interface1 hardware has a 1K RAM region which is selected into
- multiple pages.
- ---
- fuse/memory.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
- diff --git a/fuse/memory.h b/fuse/memory.h
- index 6b9c72c..23a1321 100644
- --- a/fuse/memory.h
- +++ b/fuse/memory.h
- @@ -64,7 +64,7 @@ typedef struct memory_page {
- /* A memory page will be 1 << (this many) bytes in size
- ie 12 => 4 Kb, 13 => 8 Kb, 14 => 16 Kb
- */
- -#define MEMORY_PAGE_SIZE_LOGARITHM 12
- +#define MEMORY_PAGE_SIZE_LOGARITHM 10
- /* The actual size of a memory page */
- #define MEMORY_PAGE_SIZE ( 1 << MEMORY_PAGE_SIZE_LOGARITHM )
- commit 856cbbc92d7c1c8f9b4e752b99c8c65321fadee3
- Author: Alex Badea <abadea@ixiacom.com>
- Date: Fri Jun 22 13:00:30 2012 +0300
- HACK if1: add HC uPD disk interface support
- ---
- fuse/peripherals/if1.c | 250 ++++++++++++++++++++++++++++++++++++++++++++++--
- 1 file changed, 244 insertions(+), 6 deletions(-)
- diff --git a/fuse/peripherals/if1.c b/fuse/peripherals/if1.c
- index 8fcc82e..4e53a4f 100644
- --- a/fuse/peripherals/if1.c
- +++ b/fuse/peripherals/if1.c
- @@ -40,17 +40,22 @@
- #include "memory.h"
- #include "module.h"
- #include "periph.h"
- +#include "peripherals/disk/fdd.h"
- +#include "peripherals/disk/upd_fdc.h"
- #include "settings.h"
- #include "utils.h"
- #include "ui/ui.h"
- #include "unittests/unittests.h"
- #undef IF1_DEBUG_MDR
- -#undef IF1_DEBUG_NET
- +#define IF1_DEBUG_NET
- #undef IF1_DEBUG_NET_1
- #define BUFF_EMPTY 0x100
- +//#define debug_fdc(fmt, args...) fprintf(stderr, "%s:%d: " fmt "\n", __func__, __LINE__, ## args)
- +#define debug_fdc(x...)
- +
- enum {
- SYNC_NO = 0,
- SYNC_OK = 0xff
- @@ -155,8 +160,41 @@ RS232:
- every other 0x00 + 0x## are discarded
- */
- +/*
- + HC IF1
- +
- + 7 6 5 4 3 2 1 0
- + STATUS RO $EF(239) --- --- --- --- DTR --- --- ---
- +
- + CONTRO WO $EF(239) --- --- WAT CTS --- --- --- DTA
- +
- + COMM I RO $F7(247) TXD --- --- --- --- --- --- NIN
- +
- + COMM O WO $F7(247) --- --- --- --- --- --- --- nNET/RS232
- +
- +
- + BOTH I RO $E7 TXD --- --- --- DTR --- --- NIN
- +
- +
- + FDSEL I ($05/$07) --- --- --- --- --- --- --- MOTOR_ON
- + FDSEL O ($05/$07) --- --- --- RST 555 FD1 FD2 ---
- +
- + $85 I i8272 status
- + $87 I i8272 data
- + $87 O i8272 command
- +
- +?
- + Address lines: A7 A6 A5 A4 A3 A2 A1 A0
- + $FE (spectrum port) 1 0
- + $7E (sys config) 0 0
- + $F7 (NET) 0 [not 000] 0
- + $F7 (NET) 1 [not 000] 0 1
- + $EF (CTR) [! 00] 0 1
- +
- + */
- +
- /* One 8KB memory chunk accessible by the Z80 when /ROMCS is low */
- -static memory_page if1_memory_map_romcs[MEMORY_PAGES_IN_8K];
- +static memory_page if1_memory_map_romcs[MEMORY_PAGES_IN_16K];
- /* IF1 paged out ROM activated? */
- int if1_active = 0;
- @@ -193,6 +231,7 @@ enum if1_port {
- PORT_MDR,
- PORT_CTR,
- PORT_NET,
- + PORT_BOTH,
- PORT_UNKNOWN,
- };
- @@ -201,6 +240,20 @@ static void if1_enabled_snapshot( libspectrum_snap *snap );
- static void if1_from_snapshot( libspectrum_snap *snap );
- static void if1_to_snapshot( libspectrum_snap *snap );
- +
- +#define IF1_NUM_DRIVES 2
- +upd_fdc *if1_fdc;
- +static upd_fdc_drive if1_drives[ IF1_NUM_DRIVES ];
- +
- +void if1_fdc_reset( void );
- +void if1_fdc_init( void );
- +
- +libspectrum_byte if1_fdc_status( libspectrum_word port, int *attached );
- +libspectrum_byte if1_fdc_read( libspectrum_word port, int *attached );
- +void if1_fdc_write( libspectrum_word port, libspectrum_byte data );
- +libspectrum_byte if1_fdc_sel_read( libspectrum_word port, int *attached );
- +void if1_fdc_sel_write( libspectrum_word port, libspectrum_byte data );
- +
- static module_info_t if1_module_info = {
- if1_reset,
- @@ -212,9 +265,15 @@ static module_info_t if1_module_info = {
- };
- static const periph_port_t if1_ports[] = {
- + { 0x00fd, 0x0005, if1_fdc_sel_read, if1_fdc_sel_write },
- + { 0x00ff, 0x0085, if1_fdc_status, NULL },
- + { 0x00ff, 0x0087, if1_fdc_read, if1_fdc_write },
- { 0x0018, 0x0010, if1_port_in, if1_port_out },
- { 0x0018, 0x0008, if1_port_in, if1_port_out },
- { 0x0018, 0x0000, if1_port_in, if1_port_out },
- +/*
- + { 0x0001, 0x0001, if1_port_in, if1_port_out },
- +*/
- { 0, 0, NULL, NULL }
- };
- @@ -333,8 +392,14 @@ if1_init( void )
- settings_current.snet = NULL;
- }
- + if1_fdc_init();
- +
- module_register( &if1_module_info );
- + if1_memory_source = memory_source_register( "If1r" );
- + for( i = MEMORY_PAGES_IN_8K; i < MEMORY_PAGES_IN_16K; i++ )
- + if1_memory_map_romcs[i].source = if1_memory_source;
- +
- if1_memory_source = memory_source_register( "If1" );
- for( i = 0; i < MEMORY_PAGES_IN_8K; i++ )
- if1_memory_map_romcs[i].source = if1_memory_source;
- @@ -364,6 +429,9 @@ if1_update_menu( void )
- update_menu( UMENU_ALL );
- }
- +/* The number of memory pages in 1K */
- +#define MEMORY_PAGES_IN_1K ( 1 << ( 10 - MEMORY_PAGE_SIZE_LOGARITHM ) )
- +
- static void
- if1_reset( int hard_reset GCC_UNUSED )
- {
- @@ -381,6 +449,20 @@ if1_reset( int hard_reset GCC_UNUSED )
- return;
- }
- + if (1) { /* XXX */
- + int j;
- +
- + libspectrum_byte *ram =
- + memory_pool_allocate_persistent( 1024 /* IF1_HC_RAM_LENGTH */, 1 );
- +
- + for( j = 0; j < MEMORY_PAGES_IN_8K; j++ ) {
- + memory_page *page = &if1_memory_map_romcs[MEMORY_PAGES_IN_8K + j];
- + /* HACK: assumes page size is 1K */
- + page->writable = (j % 4) >= 2;
- + page->page = ram;
- + }
- + }
- +
- machine_current->ram.romcs = 0;
- if1_ula.cts = 2; /* force to emit first out if raw */
- @@ -390,6 +472,7 @@ if1_reset( int hard_reset GCC_UNUSED )
- if1_ula.esc_in = 0;
- microdrives_reset();
- + if1_fdc_reset();
- update_menu( UMENU_ALL );
- ui_statusbar_update( UI_STATUSBAR_ITEM_MICRODRIVE,
- @@ -426,7 +509,8 @@ if1_memory_map( void )
- if( !if1_active ) return;
- memory_map_romcs_8k( 0x0000, if1_memory_map_romcs );
- - memory_map_romcs_8k( 0x2000, if1_memory_map_romcs );
- + //memory_map_romcs_8k( 0x2000, if1_memory_map_romcs );
- + memory_map_romcs_8k( 0x2000, if1_memory_map_romcs + MEMORY_PAGES_IN_8K );
- }
- static void
- @@ -527,7 +611,8 @@ static enum if1_port
- decode_port( libspectrum_word port )
- {
- switch( port & 0x0018 ) {
- - case 0x0000: return PORT_MDR;
- + //case 0x0000: return PORT_MDR;
- + case 0x0000: return PORT_BOTH;
- case 0x0008: return PORT_CTR;
- case 0x0010: return PORT_NET;
- default: return PORT_UNKNOWN;
- @@ -767,6 +852,9 @@ if1_port_in( libspectrum_word port GCC_UNUSED, int *attached )
- {
- libspectrum_byte ret = 0xff;
- + if (!(port & 0x70))
- + return 0xff;
- +
- *attached = 1;
- switch( decode_port( port ) )
- @@ -774,9 +862,14 @@ if1_port_in( libspectrum_word port GCC_UNUSED, int *attached )
- case PORT_MDR: ret &= port_mdr_in(); break;
- case PORT_CTR: ret &= port_ctr_in(); break;
- case PORT_NET: ret &= port_net_in(); break;
- + case PORT_BOTH:
- + ret = (port_net_in() & 0x81) | (port_ctr_in() & 0x08);
- + break;
- case PORT_UNKNOWN: break;
- }
- + debug_fdc("port 0x%02x (%d) --> 0x%02x", port & 0xff, decode_port(port), ret);
- +
- return ret;
- }
- @@ -1006,11 +1099,20 @@ if1_port_out( libspectrum_word port GCC_UNUSED, libspectrum_byte val )
- !!(val & 8), !!(val & 4), !!(val & 2), !!(val & 1), port);
- #endif
- + if (!(port & 0x70))
- + return;
- +
- + debug_fdc("port 0x%02x <- 0x%02x", port & 0xff, val);
- +
- switch( decode_port( port ) ) {
- case PORT_MDR: port_mdr_out( val ); break;
- - case PORT_CTR: port_ctr_out( val ); break;
- - case PORT_NET: port_net_out( val ); break;
- + case PORT_CTR: port_ctr_out( val & 0x31 ); break;
- + case PORT_NET: port_net_out( val & 0x01 ); break;
- case PORT_UNKNOWN: break;
- + case PORT_BOTH:
- + port_ctr_out(val & 0x31);
- + port_net_out(val & 0x01);
- + break;
- }
- }
- @@ -1339,3 +1441,139 @@ if1_unittest( void )
- return r;
- }
- +
- +libspectrum_byte
- +if1_fdc_status( libspectrum_word port GCC_UNUSED, int *attached )
- +{
- + libspectrum_byte ret;
- + *attached = 1;
- + ret = upd_fdc_read_status( if1_fdc );
- +// debug_fdc("port 0x%02x --> 0x%02x", port & 0xff, ret);
- + return ret;
- +}
- +
- +libspectrum_byte
- +if1_fdc_read( libspectrum_word port GCC_UNUSED, int *attached )
- +{
- + libspectrum_byte ret;
- + *attached = 1;
- + ret = upd_fdc_read_data( if1_fdc );
- + debug_fdc("port 0x%02x --> 0x%02x", port & 0xff, ret);
- + return ret;
- +}
- +
- +void
- +if1_fdc_write( libspectrum_word port GCC_UNUSED, libspectrum_byte data )
- +{
- + debug_fdc("port 0x%02x <-- 0x%02x", port & 0xff, data);
- + upd_fdc_write_data( if1_fdc, data );
- +}
- +
- +libspectrum_byte
- +if1_fdc_sel_read( libspectrum_word port GCC_UNUSED, int *attached )
- +{
- + libspectrum_byte ret;
- + *attached = 1;
- + ret = 0xff;
- + debug_fdc("port 0x%02x --> 0x%02x", port & 0xff, ret);
- + return ret;
- +}
- +
- +void
- +if1_fdc_sel_write( libspectrum_word port GCC_UNUSED, libspectrum_byte data )
- +{
- + libspectrum_byte armed;
- +
- + debug_fdc("port 0x%02x <-- 0x%02x", port & 0xff, data);
- +
- + if (!(data & 0x10)) {
- + debug_fdc("if1: FDC reset");
- + upd_fdc_master_reset(if1_fdc);
- + }
- + upd_fdc_tc(if1_fdc, data & 1);
- +
- + armed = data & 0x08;
- + if (!armed) {
- +// if1_drives[0].disk.type = DISK_TYPE_NONE;
- +// fprintf(stderr, "### disk_write log: %d\n", disk_write(&if1_drives[0].disk, "/tmp/hc-if1-disk.log")); // HACK
- + if1_drives[0].disk.type = DISK_TYPE_NONE;
- +// debug_fdc( "### disk_write udi: %d", disk_write(&if1_drives[0].disk, "/tmp/hc-if1-disk.udi")); // HACK
- + fprintf(stderr, "### disk_write mgt: %d\n", disk_write(&if1_drives[0].disk, "/tmp/hc-if1-disk.mgt")); // HACK
- +// fprintf(stderr, "### disk_write img: %d\n", disk_write(&if1_drives[0].disk, "/tmp/hc-if1-disk.img")); // HACK
- +// if1_drives[0].disk.type = DISK_LOG;
- + }
- +
- +
- + /* TODO: monostable delay */
- + //armed = data & 0x08;
- + armed = 1;
- + fdd_select(&if1_drives[0].fdd, armed && (data & 0x02));
- + fdd_select(&if1_drives[1].fdd, armed && (data & 0x04));
- + fdd_motoron(&if1_drives[0].fdd, armed && (data & 0x02));
- + fdd_motoron(&if1_drives[1].fdd, armed && (data & 0x04));
- +}
- +
- +void
- +if1_fdc_init( void )
- +{
- + upd_fdc_drive *d;
- + int err;
- +
- + if1_fdc = upd_fdc_alloc_fdc( UPD765A, UPD_CLOCK_8MHZ );
- + if1_fdc->drive[0] = &if1_drives[ 0 ];
- + if1_fdc->drive[1] = &if1_drives[ 1 ];
- + if1_fdc->drive[2] = &if1_drives[ 0 ];
- + if1_fdc->drive[3] = &if1_drives[ 1 ];
- +
- + fdd_init( &if1_drives[ 0 ].fdd, FDD_SHUGART, &fdd_params[ 4 ], 0 );
- + fdd_init( &if1_drives[ 1 ].fdd, FDD_SHUGART, &fdd_params[ 1 ], 0 ); /* drive geometry 'autodetect' */
- + if1_fdc->set_intrq = NULL;
- + if1_fdc->reset_intrq = NULL;
- + if1_fdc->set_datarq = NULL;
- + if1_fdc->reset_datarq = NULL;
- +
- + d = &if1_drives[0];
- + err = disk_open( &d->disk, "/tmp/hc-if1-disk.mgt", 0, 0);
- + fprintf(stderr, "disk_open: %d\n", err);
- + if (err) {
- + err = disk_new(&d->disk,
- + 2 /* heads */,
- + 80 /* cylinders */,
- + DISK_DENS_AUTO /* DISK_DENS_AUTO */,
- + DISK_LOG /* DISK_UDI? _NONE? */);
- + fprintf(stderr, "disk_new: %d\n", err);
- + }
- +
- + err = fdd_load( &d->fdd, &d->disk, 0 );
- + debug_fdc("fdc_load(%p): %d", &d->fdd, err);
- +
- +
- + d = &if1_drives[1];
- + if (1) {
- + err = disk_new(&d->disk,
- + 2 /* heads */,
- + 40 /* cylinders */,
- + DISK_DENS_AUTO /* DISK_DENS_AUTO */,
- + DISK_LOG /* DISK_UDI? _NONE? */);
- + fprintf(stderr, "disk_new: %d\n", err);
- + }
- + err = fdd_load( &d->fdd, &d->disk, 0 );
- + debug_fdc("fdc_load(%p): %d", &d->fdd, err);
- +}
- +
- +void
- +if1_fdc_reset( void )
- +{
- + const fdd_params_t *dt;
- +
- + upd_fdc_master_reset( if1_fdc );
- + dt = &fdd_params[4];
- + fdd_init( &if1_drives[ 0 ].fdd, FDD_SHUGART, dt, 1 );
- +
- + dt = &fdd_params[2];
- + fdd_init( &if1_drives[ 1 ].fdd, dt->enabled ? FDD_SHUGART : FDD_TYPE_NONE, dt, 1 );
- +}
- +
- +/*
- +vampire@black:~/src/fuse-emulator/fuse$ ~/build/fuse-git/fuse/fuse -m 48 --rom-48=roms/HC/HC-90/BAS --rom-interface-i=roms/HC/HC-90/IF1.trunc --interface1 > /tmp/fuse.log 2>&1
- + */
Add Comment
Please, Sign In to add comment