@@ -565,6 +565,8 @@ class tek440x_state : public driver_device
565
565
u8 mouse_r (offs_t offset);
566
566
void mouse_w (u8 data);
567
567
void led_w (u8 data);
568
+ u16 fpu_r (offs_t offset);
569
+ void fpu_w (offs_t offset, u16 data);
568
570
u16 videoaddr_r (offs_t offset);
569
571
void videoaddr_w (offs_t offset, u16 data);
570
572
u8 videocntl_r ();
@@ -638,6 +640,12 @@ class tek440x_state : public driver_device
638
640
bool m_kb_tdata;
639
641
bool m_kb_rclamp;
640
642
bool m_kb_loop;
643
+
644
+ u16 m_fpuselect;
645
+ u16 m_operand;
646
+ u16 m_lswoperand[5 ];
647
+ u16 m_mswoperand[5 ];
648
+
641
649
u16 m_videoaddr[4 ];
642
650
u8 m_videocntl;
643
651
u8 m_diag;
@@ -998,6 +1006,103 @@ void tek440x_state::mapcntl_w(u8 data)
998
1006
999
1007
}
1000
1008
1009
+
1010
+ enum {
1011
+ FLOAT = 0xbe ,
1012
+ DOUBLE = 0x3e ,
1013
+
1014
+ FADD = 0x0142 ,
1015
+ FSUB = 0x1142 ,
1016
+ FMUL = 0x3142 ,
1017
+ FDIV = 0x2142 ,
1018
+ FCMP = 0x0942 ,
1019
+
1020
+
1021
+ DMUL = 0x3342 ,
1022
+
1023
+
1024
+ };
1025
+
1026
+ void tek440x_state::fpu_w (offs_t offset, u16 data)
1027
+ {
1028
+ switch (offset)
1029
+ {
1030
+ default :
1031
+ break ;
1032
+
1033
+ // latches opcode.w, arg1.l, arg2.l
1034
+ case 2 :
1035
+ m_lswoperand[m_operand] = data;
1036
+ if (!m_operand) m_operand++;
1037
+ break ;
1038
+ case 3 :
1039
+ m_mswoperand[m_operand] = data;
1040
+ m_operand++;
1041
+ break ;
1042
+
1043
+ // select float or double
1044
+ case 6 :
1045
+ m_fpuselect = data;
1046
+ if (data != FLOAT)
1047
+ LOG (" fpu_w: DOUBLE not implemented\n " );
1048
+ m_operand = 0 ;
1049
+ break ;
1050
+ case 7 :
1051
+ break ;
1052
+ }
1053
+ }
1054
+
1055
+
1056
+ u16 tek440x_state::fpu_r (offs_t offset)
1057
+ {
1058
+ // status check
1059
+ if (offset == 4 )
1060
+ return 0 ;
1061
+
1062
+ // NB doing floating calc twice, once for low word read, again for high word read..
1063
+
1064
+ unsigned int ai = (m_mswoperand[1 ] << 16 ) | (m_lswoperand[1 ]);
1065
+ float a = *(float *)&ai;
1066
+
1067
+ unsigned int bi = (m_mswoperand[2 ] << 16 ) | (m_lswoperand[2 ]);
1068
+ float b = *(float *)&bi;
1069
+
1070
+ LOG (" fpu_r: %04x %f %f\n " ,m_lswoperand[0 ], a,b);
1071
+
1072
+ float c;
1073
+ switch (m_lswoperand[0 ])
1074
+ {
1075
+ case FADD:
1076
+ c = a + b;
1077
+ break ;
1078
+ case FSUB:
1079
+ c = a - b;
1080
+ break ;
1081
+ case FMUL:
1082
+ c = a * b;
1083
+ break ;
1084
+ case FDIV:
1085
+ c = a / b;
1086
+ break ;
1087
+ default :
1088
+ LOG (" fpu_r: unknown opcode 0x%04x\n " , m_lswoperand[0 ]);
1089
+ }
1090
+
1091
+ unsigned int ci = *(unsigned int *)&c;
1092
+ switch (offset)
1093
+ {
1094
+ default :
1095
+ return 0 ;
1096
+
1097
+ case 2 :
1098
+ return ci & 0xffff ;
1099
+
1100
+ case 3 :
1101
+ return (ci >> 16 ) & 0xffff ;
1102
+
1103
+ }
1104
+ }
1105
+
1001
1106
u16 tek440x_state::videoaddr_r (offs_t offset)
1002
1107
{
1003
1108
LOG (" videoaddr_r %08x\n " , offset);
@@ -1346,7 +1451,7 @@ void tek440x_state::physical_map(address_map &map)
1346
1451
map (0x784000 , 0x784000 ).rw (FUNC (tek440x_state::videocntl_r),FUNC (tek440x_state::videocntl_w));
1347
1452
// 786000-787fff: spare
1348
1453
map (0x788000 , 0x788000 ).w (FUNC (tek440x_state::sound_w));
1349
- // 78a000-78bfff: NS32081 FPU
1454
+ map ( 0x78a000 , 0x78bfff ). rw ( FUNC (tek440x_state::fpu_r), FUNC (tek440x_state::fpu_w));
1350
1455
map (0x78c000 , 0x78c007 ).rw (m_acia, FUNC (mos6551_device::read), FUNC (mos6551_device::write)).umask16 (0xff00 );
1351
1456
// 78e000-78ffff: spare
1352
1457
0 commit comments