2015-11-05 20:23:46 +00:00
/*
2018-08-13 17:22:40 +00:00
GSPLUS - Advanced Apple IIGS Emulator Environment
Based on the KEGS emulator written by Kent Dickey
See COPYRIGHT . txt for Copyright information
See LICENSE . txt for license ( GPL v2 )
*/
2015-11-05 20:23:46 +00:00
# include "defc.h"
2016-10-28 16:42:50 +00:00
# include "glog.h"
2015-11-05 20:23:46 +00:00
extern int Verbose ;
extern int Halt_on ;
extern int g_rom_version ;
extern int g_io_amt ;
extern int g_highest_smartport_unit ;
word32 g_cycs_in_io_read = 0 ;
extern Engine_reg engine ;
extern Iwm iwm ;
2018-08-13 17:22:40 +00:00
# define LEN_SMPT_LOG 16
2015-11-05 20:23:46 +00:00
STRUCT ( Smpt_log ) {
2018-08-13 17:22:40 +00:00
word32 start_addr ;
int cmd ;
int rts_addr ;
int cmd_list ;
int extras ;
int unit ;
int buf ;
int blk ;
2015-11-05 20:23:46 +00:00
} ;
Smpt_log g_smpt_log [ LEN_SMPT_LOG ] ;
2018-08-13 17:22:40 +00:00
int g_smpt_log_pos = 0 ;
void smartport_error ( void ) {
int pos ;
int i ;
pos = g_smpt_log_pos ;
printf ( " Smartport log pos: %d \n " , pos ) ;
for ( i = 0 ; i < LEN_SMPT_LOG ; i + + ) {
pos - - ;
if ( pos < 0 ) {
pos = LEN_SMPT_LOG - 1 ;
}
printf ( " %d:%d: t:%04x, cmd:%02x, rts:%04x, "
" cmd_l:%04x, x:%d, unit:%d, buf:%04x, blk:%04x \n " ,
i , pos ,
g_smpt_log [ pos ] . start_addr ,
g_smpt_log [ pos ] . cmd ,
g_smpt_log [ pos ] . rts_addr ,
g_smpt_log [ pos ] . cmd_list ,
g_smpt_log [ pos ] . extras ,
g_smpt_log [ pos ] . unit ,
g_smpt_log [ pos ] . buf ,
g_smpt_log [ pos ] . blk ) ;
}
2015-11-05 20:23:46 +00:00
}
2018-08-13 17:22:40 +00:00
void smartport_log ( word32 start_addr , int cmd , int rts_addr , int cmd_list ) {
int pos ;
pos = g_smpt_log_pos ;
if ( start_addr ! = 0 ) {
g_smpt_log [ pos ] . start_addr = start_addr ;
g_smpt_log [ pos ] . cmd = cmd ;
g_smpt_log [ pos ] . rts_addr = rts_addr ;
g_smpt_log [ pos ] . cmd_list = cmd_list ;
g_smpt_log [ pos ] . extras = 0 ;
g_smpt_log [ pos ] . unit = 0 ;
g_smpt_log [ pos ] . buf = 0 ;
g_smpt_log [ pos ] . blk = 0 ;
} else {
pos - - ;
if ( pos < 0 ) {
pos = LEN_SMPT_LOG - 1 ;
}
g_smpt_log [ pos ] . extras = 1 ;
g_smpt_log [ pos ] . unit = cmd ;
g_smpt_log [ pos ] . buf = rts_addr ;
g_smpt_log [ pos ] . blk = cmd_list ;
}
pos + + ;
if ( pos > = LEN_SMPT_LOG ) {
pos = 0 ;
}
g_smpt_log_pos = pos ;
2015-11-05 20:23:46 +00:00
}
2018-08-13 17:22:40 +00:00
void do_c70d ( word32 arg0 ) {
int cmd ;
int cmd_list_lo , cmd_list_mid , cmd_list_hi ;
int rts_lo , rts_hi ;
word32 rts_addr ;
word32 cmd_list ;
int unit ;
int param_cnt ;
int status_ptr_lo , status_ptr_mid , status_ptr_hi ;
int buf_ptr_lo , buf_ptr_hi ;
int buf_ptr ;
int block_lo , block_mid , block_hi ;
int block ;
word32 status_ptr ;
int status_code ;
int ctl_ptr_lo , ctl_ptr_hi ;
int ctl_ptr ;
int ctl_code ;
int mask ;
int stat_val ;
int size ;
int ret ;
int ext ;
int i ;
set_memory_c ( 0x7f8 , 0xc7 , 0 ) ;
if ( ( engine . psr & 0x100 ) = = 0 ) {
disk_printf ( " c70d called in native mode! \n " ) ;
if ( ( engine . psr & 0x30 ) ! = 0x30 ) {
halt_printf ( " c70d called native, psr: %03x! \n " ,
engine . psr ) ;
}
}
engine . stack = ( ( engine . stack + 1 ) & 0xff ) + 0x100 ;
rts_lo = get_memory_c ( engine . stack , 0 ) ;
engine . stack = ( ( engine . stack + 1 ) & 0xff ) + 0x100 ;
rts_hi = get_memory_c ( engine . stack , 0 ) ;
rts_addr = ( rts_lo + ( 256 * rts_hi ) + 1 ) & 0xffff ;
disk_printf ( " rts_addr: %04x \n " , rts_addr ) ;
cmd = get_memory_c ( rts_addr , 0 ) ;
cmd_list_lo = get_memory_c ( ( rts_addr + 1 ) & 0xffff , 0 ) ;
cmd_list_mid = get_memory_c ( ( rts_addr + 2 ) & 0xffff , 0 ) ;
cmd_list_hi = 0 ;
mask = 0xffff ;
if ( cmd & 0x40 ) {
/* extended */
mask = 0xffffff ;
cmd_list_hi = get_memory_c ( ( rts_addr + 3 ) & 0xffff , 0 ) ;
}
cmd_list = cmd_list_lo + ( 256 * cmd_list_mid ) + ( 65536 * cmd_list_hi ) ;
disk_printf ( " cmd: %02x, cmd_list: %06x \n " , cmd , cmd_list ) ;
param_cnt = get_memory_c ( cmd_list , 0 ) ;
ext = 0 ;
if ( cmd & 0x40 ) {
ext = 2 ;
}
smartport_log ( 0xc70d , cmd , rts_addr , cmd_list ) ;
switch ( cmd & 0x3f ) {
case 0x00 : /* Status == 0x00 and 0x40 */
if ( param_cnt ! = 3 ) {
disk_printf ( " param_cnt %d is != 3! \n " , param_cnt ) ;
exit ( 8 ) ;
}
unit = get_memory_c ( ( cmd_list + 1 ) & mask , 0 ) ;
status_ptr_lo = get_memory_c ( ( cmd_list + 2 ) & mask , 0 ) ;
status_ptr_mid = get_memory_c ( ( cmd_list + 3 ) & mask , 0 ) ;
status_ptr_hi = 0 ;
if ( cmd & 0x40 ) {
status_ptr_hi = get_memory_c ( ( cmd_list + 4 ) & mask , 0 ) ;
}
status_ptr = status_ptr_lo + ( 256 * status_ptr_mid ) +
( 65536 * status_ptr_hi ) ;
if ( cmd & 0x40 ) {
status_code = get_memory_c ( ( cmd_list + 6 ) & mask , 0 ) ;
} else {
status_code = get_memory_c ( ( cmd_list + 4 ) & mask , 0 ) ;
}
smartport_log ( 0 , unit , status_ptr , status_code ) ;
disk_printf ( " unit: %02x, status_ptr: %06x, code: %02x \n " ,
unit , status_ptr , status_code ) ;
if ( unit = = 0 & & status_code = = 0 ) {
/* Smartport driver status */
/* see technotes/smpt/tn-smpt-002 */
set_memory_c ( status_ptr , g_highest_smartport_unit + 1 , 0 ) ;
set_memory_c ( status_ptr + 1 , 0xff , 0 ) ; /* interrupt stat*/
set_memory16_c ( status_ptr + 2 , 0x0002 , 0 ) ; /* vendor id */
set_memory16_c ( status_ptr + 4 , 0x1000 , 0 ) ; /* version */
set_memory16_c ( status_ptr + 6 , 0x0000 , 0 ) ;
engine . xreg = 8 ;
engine . yreg = 0 ;
engine . acc & = 0xff00 ;
engine . psr & = ~ 1 ;
engine . kpc = ( rts_addr + 3 + ext ) & mask ;
return ;
} else if ( unit > 0 & & status_code = = 0 ) {
/* status for unit x */
if ( unit > MAX_C7_DISKS | | ( ! iwm . smartport [ unit - 1 ] . file ) ) {
stat_val = 0x80 ;
size = 0 ;
} else {
stat_val = 0xf8 ;
size = iwm . smartport [ unit - 1 ] . image_size ;
size = ( size + 511 ) / 512 ;
}
set_memory_c ( status_ptr , stat_val , 0 ) ;
set_memory24_c ( status_ptr + 1 , size , 0 ) ;
engine . xreg = 4 ;
if ( cmd & 0x40 ) {
set_memory_c ( status_ptr + 4 ,
( size > > 16 ) & 0xff , 0 ) ;
engine . xreg = 5 ;
}
engine . yreg = 0 ;
engine . acc & = 0xff00 ;
engine . psr & = ~ 1 ;
engine . kpc = ( rts_addr + 3 + ext ) & mask ;
disk_printf ( " just finished unit %d, stat 0 \n " , unit ) ;
return ;
} else if ( status_code = = 3 ) {
if ( unit > MAX_C7_DISKS | | ( ! iwm . smartport [ unit - 1 ] . file ) ) {
stat_val = 0x80 ;
size = 0 ;
} else {
stat_val = 0xf8 ;
size = iwm . smartport [ unit - 1 ] . image_size ;
size = ( size + 511 ) / 512 ;
}
if ( cmd & 0x40 ) {
disk_printf ( " extended for stat_code 3! \n " ) ;
}
/* DIB for unit 1 */
set_memory_c ( status_ptr , stat_val , 0 ) ;
set_memory24_c ( status_ptr + 1 , size , 0 ) ;
if ( cmd & 0x40 ) {
set_memory_c ( status_ptr + 4 ,
( size > > 24 ) & 0xff , 0 ) ;
status_ptr + + ;
}
set_memory_c ( status_ptr + 4 , 4 , 0 ) ;
for ( i = 5 ; i < 21 ; i + + ) {
set_memory_c ( status_ptr + i , 0x20 , 0 ) ;
}
set_memory_c ( status_ptr + 5 , ' K ' , 0 ) ;
set_memory_c ( status_ptr + 6 , ' E ' , 0 ) ;
set_memory_c ( status_ptr + 7 , ' G ' , 0 ) ;
set_memory_c ( status_ptr + 8 , ' S ' , 0 ) ;
/* hard disk supporting extended calls */
set_memory16_c ( status_ptr + 21 , 0xa002 , 0 ) ;
set_memory16_c ( status_ptr + 23 , 0x0000 , 0 ) ;
if ( cmd & 0x40 ) {
engine . xreg = 26 ;
} else {
engine . xreg = 25 ;
}
engine . yreg = 0 ;
engine . acc & = 0xff00 ;
engine . psr & = ~ 1 ;
engine . kpc = ( rts_addr + 3 + ext ) & 0xffff ;
disk_printf ( " Just finished unit %d, stat 3 \n " , unit ) ;
if ( unit = = 0 | | unit > MAX_C7_DISKS ) {
engine . acc | = 0x28 ;
engine . psr | = 1 ;
}
return ;
}
printf ( " cmd: 00, unknown unit/status code! \n " ) ;
break ;
case 0x01 : /* Read Block == 0x01 and 0x41 */
if ( param_cnt ! = 3 ) {
halt_printf ( " param_cnt %d is != 3! \n " , param_cnt ) ;
return ;
}
unit = get_memory_c ( ( cmd_list + 1 ) & mask , 0 ) ;
buf_ptr_lo = get_memory_c ( ( cmd_list + 2 ) & mask , 0 ) ;
buf_ptr_hi = get_memory_c ( ( cmd_list + 3 ) & mask , 0 ) ;
buf_ptr = buf_ptr_lo + ( 256 * buf_ptr_hi ) ;
if ( cmd & 0x40 ) {
buf_ptr_lo = get_memory_c ( ( cmd_list + 4 ) & mask , 0 ) ;
buf_ptr_hi = get_memory_c ( ( cmd_list + 5 ) & mask , 0 ) ;
buf_ptr + = ( ( buf_ptr_hi * 256 ) + buf_ptr_lo ) * 65536 ;
cmd_list + = 2 ;
}
block_lo = get_memory_c ( ( cmd_list + 4 ) & mask , 0 ) ;
block_mid = get_memory_c ( ( cmd_list + 5 ) & mask , 0 ) ;
block_hi = get_memory_c ( ( cmd_list + 6 ) & mask , 0 ) ;
block = ( ( block_hi * 256 ) + block_mid ) * 256 + block_lo ;
disk_printf ( " smartport read unit %d of block %04x into %04x \n " ,
unit , block , buf_ptr ) ;
if ( unit < 1 | | unit > MAX_C7_DISKS ) {
halt_printf ( " Unknown unit #: %d \n " , unit ) ;
}
smartport_log ( 0 , unit - 1 , buf_ptr , block ) ;
ret = do_read_c7 ( unit - 1 , buf_ptr , block ) ;
engine . xreg = 0 ;
engine . yreg = 2 ;
engine . acc = ( engine . acc & 0xff00 ) | ( ret & 0xff ) ;
engine . psr & = ~ 1 ;
if ( ret ! = 0 ) {
engine . psr | = 1 ;
}
engine . kpc = ( rts_addr + 3 + ext ) & 0xffff ;
return ;
break ;
case 0x02 : /* Write Block == 0x02 and 0x42 */
if ( param_cnt ! = 3 ) {
halt_printf ( " param_cnt %d is != 3! \n " , param_cnt ) ;
return ;
}
unit = get_memory_c ( ( cmd_list + 1 ) & mask , 0 ) ;
buf_ptr_lo = get_memory_c ( ( cmd_list + 2 ) & mask , 0 ) ;
buf_ptr_hi = get_memory_c ( ( cmd_list + 3 ) & mask , 0 ) ;
buf_ptr = buf_ptr_lo + ( 256 * buf_ptr_hi ) ;
if ( cmd & 0x40 ) {
buf_ptr_lo = get_memory_c ( ( cmd_list + 4 ) & mask , 0 ) ;
buf_ptr_hi = get_memory_c ( ( cmd_list + 5 ) & mask , 0 ) ;
buf_ptr + = ( ( buf_ptr_hi * 256 ) + buf_ptr_lo ) * 65536 ;
cmd_list + = 2 ;
}
block_lo = get_memory_c ( ( cmd_list + 4 ) & mask , 0 ) ;
block_mid = get_memory_c ( ( cmd_list + 5 ) & mask , 0 ) ;
block_hi = get_memory_c ( ( cmd_list + 6 ) & mask , 0 ) ;
block = ( ( block_hi * 256 ) + block_mid ) * 256 + block_lo ;
disk_printf ( " smartport write unit %d of block %04x from %04x \n " ,
unit , block , buf_ptr ) ;
if ( unit < 1 | | unit > MAX_C7_DISKS ) {
halt_printf ( " Unknown unit #: %d \n " , unit ) ;
}
smartport_log ( 0 , unit - 1 , buf_ptr , block ) ;
ret = do_write_c7 ( unit - 1 , buf_ptr , block ) ;
engine . xreg = 0 ;
engine . yreg = 2 ;
engine . acc = ( engine . acc & 0xff00 ) | ( ret & 0xff ) ;
engine . psr & = ~ 1 ;
if ( ret ! = 0 ) {
engine . psr | = 1 ;
}
engine . kpc = ( rts_addr + 3 + ext ) & 0xffff ;
HALT_ON ( HALT_ON_C70D_WRITES , " c70d Write done \n " ) ;
return ;
break ;
case 0x03 : /* Format == 0x03 and 0x43 */
if ( param_cnt ! = 1 ) {
halt_printf ( " param_cnt %d is != 1! \n " , param_cnt ) ;
return ;
}
unit = get_memory_c ( ( cmd_list + 1 ) & mask , 0 ) ;
if ( unit < 1 | | unit > MAX_C7_DISKS ) {
halt_printf ( " Unknown unit #: %d \n " , unit ) ;
}
smartport_log ( 0 , unit - 1 , 0 , 0 ) ;
ret = do_format_c7 ( unit - 1 ) ;
engine . xreg = 0 ;
engine . yreg = 2 ;
engine . acc = ( engine . acc & 0xff00 ) | ( ret & 0xff ) ;
engine . psr & = ~ 1 ;
if ( ret ! = 0 ) {
engine . psr | = 1 ;
}
engine . kpc = ( rts_addr + 3 + ext ) & 0xffff ;
HALT_ON ( HALT_ON_C70D_WRITES , " c70d Format done \n " ) ;
return ;
break ;
case 0x04 : /* Control == 0x04 and 0x44 */
if ( cmd = = 0x44 ) {
halt_printf ( " smartport code 0x44 not supported \n " ) ;
}
if ( param_cnt ! = 3 ) {
halt_printf ( " param_cnt %d is != 3! \n " , param_cnt ) ;
return ;
}
unit = get_memory_c ( ( cmd_list + 1 ) & mask , 0 ) ;
ctl_ptr_lo = get_memory_c ( ( cmd_list + 2 ) & mask , 0 ) ;
ctl_ptr_hi = get_memory_c ( ( cmd_list + 3 ) & mask , 0 ) ;
ctl_ptr = ( ctl_ptr_hi < < 8 ) + ctl_ptr_lo ;
if ( cmd & 0x40 ) {
ctl_ptr_lo = get_memory_c ( ( cmd_list + 4 ) & mask , 0 ) ;
ctl_ptr_hi = get_memory_c ( ( cmd_list + 5 ) & mask , 0 ) ;
ctl_ptr + = ( ( ctl_ptr_hi < < 8 ) + ctl_ptr_lo ) < < 16 ;
cmd_list + = 2 ;
}
ctl_code = get_memory_c ( ( cmd_list + 4 ) & mask , 0 ) ;
switch ( ctl_code ) {
case 0x00 :
printf ( " Performing a reset on unit %d \n " , unit ) ;
break ;
default :
halt_printf ( " control code: %02x unknown! \n " , ctl_code ) ;
}
engine . xreg = 0 ;
engine . yreg = 2 ;
engine . acc & = 0xff00 ;
engine . psr & = ~ 1 ;
engine . kpc = ( rts_addr + 3 + ext ) & 0xffff ;
return ;
break ;
default : /* Unknown command! */
/* set acc = 1, and set carry, and set kpc */
engine . xreg = ( rts_addr ) & 0xff ;
engine . yreg = ( rts_addr > > 8 ) & 0xff ;
engine . acc = ( engine . acc & 0xff00 ) + 0x01 ;
engine . psr | = 0x01 ; /* set carry */
engine . kpc = ( rts_addr + 3 + ext ) & 0xffff ;
if ( cmd ! = 0x4a & & cmd ! = 0x48 ) {
/* Finder does 0x4a call before formatting disk */
/* Many things do 0x48 call to see online drives */
halt_printf ( " Just did smtport cmd:%02x rts_addr:%04x, "
" cmdlst:%06x \n " , cmd , rts_addr , cmd_list ) ;
}
return ;
}
halt_printf ( " Unknown smtport cmd:%02x, cmd_list:%06x, rts_addr:%06x \n " ,
cmd , cmd_list , rts_addr ) ;
2015-11-05 20:23:46 +00:00
}
2018-08-13 17:22:40 +00:00
void do_c70a ( word32 arg0 ) {
int cmd , unit ;
int buf_lo , buf_hi ;
int blk_lo , blk_hi ;
int blk , buf ;
int prodos_unit ;
int size ;
int ret ;
set_memory_c ( 0x7f8 , 0xc7 , 0 ) ;
cmd = get_memory_c ( ( engine . direct + 0x42 ) & 0xffff , 0 ) ;
prodos_unit = get_memory_c ( ( engine . direct + 0x43 ) & 0xffff , 0 ) ;
buf_lo = get_memory_c ( ( engine . direct + 0x44 ) & 0xffff , 0 ) ;
buf_hi = get_memory_c ( ( engine . direct + 0x45 ) & 0xffff , 0 ) ;
blk_lo = get_memory_c ( ( engine . direct + 0x46 ) & 0xffff , 0 ) ;
blk_hi = get_memory_c ( ( engine . direct + 0x47 ) & 0xffff , 0 ) ;
blk = ( blk_hi < < 8 ) + blk_lo ;
buf = ( buf_hi < < 8 ) + buf_lo ;
disk_printf ( " cmd: %02x, pro_unit: %02x, buf: %04x, blk: %04x \n " ,
cmd , prodos_unit , buf , blk ) ;
if ( ( prodos_unit & 0x7f ) = = 0x70 ) {
unit = 0 + ( prodos_unit > > 7 ) ;
} else if ( ( prodos_unit & 0x7f ) = = 0x40 ) {
unit = 2 + ( prodos_unit > > 7 ) ;
} else {
halt_printf ( " Unknown prodos_unit: %d \n " , prodos_unit ) ;
return ;
}
smartport_log ( 0xc70a , cmd , blk , buf ) ;
engine . psr & = ~ 1 ; /* clear carry */
if ( g_rom_version > = 3 ) {
engine . kpc = 0xc764 ;
} else {
engine . kpc = 0xc765 ;
}
ret = 0x27 ; /* I/O error */
if ( cmd = = 0x00 ) {
size = iwm . smartport [ unit ] . image_size ;
size = ( size + 511 ) / 512 ;
smartport_log ( 0 , unit , size , 0 ) ;
ret = 0 ;
engine . xreg = size & 0xff ;
engine . yreg = size > > 8 ;
} else if ( cmd = = 0x01 ) {
smartport_log ( 0 , unit , buf , blk ) ;
ret = do_read_c7 ( unit , buf , blk ) ;
} else if ( cmd = = 0x02 ) {
smartport_log ( 0 , unit , buf , blk ) ;
ret = do_write_c7 ( unit , buf , blk ) ;
} else if ( cmd = = 0x03 ) { /* format */
smartport_log ( 0 , unit , buf , blk ) ;
ret = do_format_c7 ( unit ) ;
}
engine . acc = ( engine . acc & 0xff00 ) | ( ret & 0xff ) ;
if ( ret ! = 0 ) {
engine . psr | = 1 ;
}
return ;
2015-11-05 20:23:46 +00:00
}
2018-08-13 17:22:40 +00:00
int do_read_c7 ( int unit_num , word32 buf , int blk ) {
byte local_buf [ 0x200 ] ;
register word32 start_time ;
register word32 end_time ;
word32 val ;
FILE * file ;
int len ;
int image_start ;
int image_size ;
int ret ;
int i ;
if ( unit_num < 0 | | unit_num > MAX_C7_DISKS ) {
halt_printf ( " do_read_c7: unit_num: %d \n " , unit_num ) ;
smartport_error ( ) ;
return 0x28 ;
}
file = iwm . smartport [ unit_num ] . file ;
image_start = iwm . smartport [ unit_num ] . image_start ;
image_size = iwm . smartport [ unit_num ] . image_size ;
if ( ! file ) {
glog ( " Trying file mapped to $C7xx, but it's null! " ) ;
2015-11-05 20:23:46 +00:00
#if 0
2018-08-13 17:22:40 +00:00
if ( blk ! = 2 & & blk ! = 0 ) {
/* don't print error if only reading directory */
smartport_error ( ) ;
halt_printf ( " Read unit:%02x blk:%04x \n " , unit_num , blk ) ;
}
2015-11-05 20:23:46 +00:00
# endif
2018-08-13 17:22:40 +00:00
return 0x2f ;
}
2015-11-05 20:23:46 +00:00
2018-08-13 17:22:40 +00:00
ret = fseek ( file , image_start + blk * 0x200 , SEEK_SET ) ;
if ( ret ! = 0 ) {
halt_printf ( " fseek errno: %d \n " , errno ) ;
smartport_error ( ) ;
return 0x27 ;
}
2015-11-05 20:23:46 +00:00
2018-08-13 17:22:40 +00:00
if ( image_start + blk * 0x200 > image_start + image_size ) {
halt_printf ( " Tried to read from pos %08x on disk, (blk:%04x) \n " ,
image_start + blk * 0x200 , blk ) ;
smartport_error ( ) ;
return 0x27 ;
}
2015-11-05 20:23:46 +00:00
2018-08-13 17:22:40 +00:00
len = fread ( & local_buf [ 0 ] , 1 , 0x200 , file ) ;
if ( len ! = 0x200 ) {
printf ( " fread returned %08x, errno:%d, blk:%04x, unit: %02x \n " ,
len , errno , blk , unit_num ) ;
halt_printf ( " name: %s \n " , iwm . smartport [ unit_num ] . name_ptr ) ;
smartport_error ( ) ;
return 0x27 ;
}
2015-11-05 20:23:46 +00:00
2018-08-13 17:22:40 +00:00
g_io_amt + = 0x200 ;
2015-11-05 20:23:46 +00:00
2018-08-13 17:22:40 +00:00
if ( buf > = 0xfc0000 ) {
disk_printf ( " reading into ROM, just returning \n " ) ;
return 0 ;
}
2015-11-05 20:23:46 +00:00
2018-08-13 17:22:40 +00:00
GET_ITIMER ( start_time ) ;
2015-11-05 20:23:46 +00:00
2018-08-13 17:22:40 +00:00
for ( i = 0 ; i < 0x200 ; i + = 2 ) {
val = ( local_buf [ i + 1 ] < < 8 ) + local_buf [ i ] ;
set_memory16_c ( buf + i , val , 0 ) ;
}
2015-11-05 20:23:46 +00:00
2018-08-13 17:22:40 +00:00
GET_ITIMER ( end_time ) ;
2015-11-05 20:23:46 +00:00
2018-08-13 17:22:40 +00:00
g_cycs_in_io_read + = ( end_time - start_time ) ;
2015-11-05 20:23:46 +00:00
2018-08-13 17:22:40 +00:00
return 0 ;
2015-11-05 20:23:46 +00:00
}
2018-08-13 17:22:40 +00:00
int do_write_c7 ( int unit_num , word32 buf , int blk ) {
word32 local_buf [ 0x200 / 4 ] ;
Disk * dsk ;
word32 * ptr ;
word32 val1 , val2 ;
word32 val ;
FILE * file ;
int len ;
int ret ;
int image_start ;
int image_size ;
int i ;
if ( unit_num < 0 | | unit_num > MAX_C7_DISKS ) {
halt_printf ( " do_write_c7: unit_num: %d \n " , unit_num ) ;
smartport_error ( ) ;
return 0x28 ;
}
dsk = & ( iwm . smartport [ unit_num ] ) ;
file = dsk - > file ;
image_start = dsk - > image_start ;
image_size = dsk - > image_size ;
if ( ! file ) {
halt_printf ( " c7_file is null! \n " ) ;
smartport_error ( ) ;
return 0x28 ;
}
ptr = & ( local_buf [ 0 ] ) ;
for ( i = 0 ; i < 0x200 ; i + = 4 ) {
val1 = get_memory16_c ( buf + i , 0 ) ;
val2 = get_memory16_c ( buf + i + 2 , 0 ) ;
/* reorder the little-endian bytes to be big-endian */
2016-04-28 02:58:38 +00:00
# if defined(GSPLUS_LITTLE_ENDIAN) || defined (__LITTLE_ENDIAN__) // OSX needs to calculate endianness mid-compilation, can't be passed on compile command
2018-08-13 17:22:40 +00:00
val = ( val2 < < 16 ) + val1 ;
2015-11-05 20:23:46 +00:00
# else
2018-08-13 17:22:40 +00:00
val = ( val1 < < 24 ) + ( ( val1 < < 8 ) & 0xff0000 ) +
( ( val2 < < 8 ) & 0xff00 ) + ( val2 > > 8 ) ;
2015-11-05 20:23:46 +00:00
# endif
2018-08-13 17:22:40 +00:00
* ptr + + = val ;
}
ret = fseek ( file , image_start + blk * 0x200 , SEEK_SET ) ;
if ( ret ! = 0 ) {
halt_printf ( " fseek errno: %d \n " , errno ) ;
smartport_error ( ) ;
return 0x27 ;
}
if ( image_start + blk * 0x200 > image_start + image_size ) {
halt_printf ( " Tried to write to %08x \n " , ret ) ;
smartport_error ( ) ;
return 0x27 ;
}
if ( dsk - > write_prot ) {
printf ( " Write, but %s is write protected! \n " , dsk - > name_ptr ) ;
return 0x2b ;
}
if ( dsk - > write_through_to_unix = = 0 ) {
halt_printf ( " Write to %s, but not wr_thru! \n " , dsk - > name_ptr ) ;
return 0x00 ;
}
len = fwrite ( ( byte * ) & local_buf [ 0 ] , 1 , 0x200 , file ) ;
if ( len ! = 0x200 ) {
halt_printf ( " fwrite ret %08x bytes, errno: %d \n " , len , errno ) ;
smartport_error ( ) ;
return 0x27 ;
}
g_io_amt + = 0x200 ;
return 0 ;
2015-11-05 20:23:46 +00:00
}
2018-08-13 17:22:40 +00:00
int do_format_c7 ( int unit_num ) {
byte local_buf [ 0x1000 ] ;
Disk * dsk ;
FILE * file ;
int len ;
int ret ;
int sum ;
int total ;
int max ;
int image_start ;
int image_size ;
int i ;
if ( unit_num < 0 | | unit_num > MAX_C7_DISKS ) {
halt_printf ( " do_format_c7: unit_num: %d \n " , unit_num ) ;
smartport_error ( ) ;
return 0x28 ;
}
dsk = & ( iwm . smartport [ unit_num ] ) ;
file = dsk - > file ;
image_start = dsk - > image_start ;
image_size = dsk - > image_size ;
if ( ! file ) {
halt_printf ( " c7_file is null! \n " ) ;
smartport_error ( ) ;
return 0x28 ;
}
for ( i = 0 ; i < 0x1000 ; i + + ) {
local_buf [ i ] = 0 ;
}
ret = fseek ( file , image_start , SEEK_SET ) ;
if ( ret ! = 0 ) {
halt_printf ( " fseek errno: %d \n " , errno ) ;
smartport_error ( ) ;
return 0x27 ;
}
if ( dsk - > write_prot ) {
printf ( " Format, but %s is write protected! \n " , dsk - > name_ptr ) ;
return 0x2b ;
}
if ( dsk - > write_through_to_unix = = 0 ) {
printf ( " Format of %s ignored \n " , dsk - > name_ptr ) ;
return 0x00 ;
}
sum = 0 ;
total = image_size ;
while ( sum < total ) {
max = MIN ( 0x1000 , total - sum ) ;
len = fwrite ( & local_buf [ 0 ] , 1 , max , file ) ;
if ( len ! = max ) {
halt_printf ( " write ret %08x, errno:%d \n " , len , errno ) ;
smartport_error ( ) ;
return 0x27 ;
}
sum + = len ;
}
return 0 ;
2015-11-05 20:23:46 +00:00
}
extern byte g_bram [ 2 ] [ 256 ] ;
extern byte * g_bram_ptr ;
extern byte g_temp_boot_slot ;
extern byte g_orig_boot_slot ;
2016-04-28 02:58:38 +00:00
extern int g_config_gsplus_update_needed ;
2018-08-13 17:22:40 +00:00
void do_c700 ( word32 ret ) {
disk_printf ( " do_c700 called, ret: %08x \n " , ret ) ;
if ( g_temp_boot_slot ! = 254 ) {
// Booting from slot 7 - now is a good time to turn off the temp boot slot, if it was on.
g_temp_boot_slot = 254 ;
g_bram_ptr [ 40 ] = g_orig_boot_slot ;
clk_calculate_bram_checksum ( ) ;
g_config_gsplus_update_needed = 1 ;
}
ret = do_read_c7 ( 0 , 0x800 , 0 ) ;
set_memory_c ( 0x7f8 , 7 , 0 ) ;
set_memory16_c ( 0x42 , 0x7001 , 0 ) ;
set_memory16_c ( 0x44 , 0x0800 , 0 ) ;
set_memory16_c ( 0x46 , 0x0000 , 0 ) ;
engine . xreg = 0x70 ;
engine . kpc = 0x801 ;
if ( ret ! = 0 ) {
glog ( " Failure reading boot disk in s7d1! " ) ;
glog ( " Press <F4> to enter config menu, or edit your config " ) ;
glog ( " file if you intended to use slot slot 7. " ) ;
engine . kpc = 0xff59 ; /* Jump to monitor, fix $36-$39 */
}
2015-11-05 20:23:46 +00:00
}