8
8
* the datasheet)
9
9
*
10
10
* Copyright (C) 2019, 2020 Uri Shaked
11
+ * Copyright (C) 2021 Dario Götze
11
12
*/
12
13
14
+ import { u8 , u16 , u32 } from '../types' ;
13
15
import { CPU } from './cpu' ;
14
- import { u16 } from '../types' ;
15
16
16
- function isTwoWordInstruction ( opcode : u16 ) {
17
+ function isTwoWordInstruction ( opcode : u16 ) : boolean {
17
18
return (
18
19
/* LDS */
19
20
( opcode & 0xfe0f ) === 0x9000 ||
@@ -26,8 +27,8 @@ function isTwoWordInstruction(opcode: u16) {
26
27
) ;
27
28
}
28
29
29
- export function avrInstruction ( cpu : CPU ) {
30
- const opcode = cpu . progMem [ cpu . pc ] ;
30
+ export function avrInstruction ( cpu : CPU ) : void {
31
+ const opcode : u32 = cpu . progMem [ cpu . pc ] ;
31
32
32
33
if ( ( opcode & 0xfc00 ) === 0x1c00 ) {
33
34
/* ADC, 0001 11rd dddd rrrr */
@@ -63,7 +64,7 @@ export function avrInstruction(cpu: CPU) {
63
64
const addr = 2 * ( ( opcode & 0x30 ) >> 4 ) + 24 ;
64
65
const value = cpu . dataView . getUint16 ( addr , true ) ;
65
66
const R = ( value + ( ( opcode & 0xf ) | ( ( opcode & 0xc0 ) >> 2 ) ) ) & 0xffff ;
66
- cpu . dataView . setUint16 ( addr , R , true ) ;
67
+ cpu . dataView . setUint16 ( addr , u16 ( R ) , true ) ;
67
68
let sreg = cpu . data [ 95 ] & 0xe0 ;
68
69
sreg |= R ? 0 : 2 ;
69
70
sreg |= 0x8000 & R ? 4 : 0 ;
@@ -104,38 +105,38 @@ export function avrInstruction(cpu: CPU) {
104
105
cpu . data [ 95 ] = sreg ;
105
106
} else if ( ( opcode & 0xff8f ) === 0x9488 ) {
106
107
/* BCLR, 1001 0100 1sss 1000 */
107
- cpu . data [ 95 ] &= ~ ( 1 << ( ( opcode & 0x70 ) >> 4 ) ) ;
108
+ cpu . data [ 95 ] &= ~ ( 1 << u8 ( ( opcode & 0x70 ) >> 4 ) ) ;
108
109
} else if ( ( opcode & 0xfe08 ) === 0xf800 ) {
109
110
/* BLD, 1111 100d dddd 0bbb */
110
111
const b = opcode & 7 ;
111
112
const d = ( opcode & 0x1f0 ) >> 4 ;
112
- cpu . data [ d ] = ( ~ ( 1 << b ) & cpu . data [ d ] ) | ( ( ( cpu . data [ 95 ] >> 6 ) & 1 ) << b ) ;
113
+ cpu . data [ d ] = ( ~ ( 1 << b ) & cpu . data [ d ] ) | ( ( ( cpu . data [ 95 ] >> 6 ) & 1 ) << u8 ( b ) ) ;
113
114
} else if ( ( opcode & 0xfc00 ) === 0xf400 ) {
114
115
/* BRBC, 1111 01kk kkkk ksss */
115
- if ( ! ( cpu . data [ 95 ] & ( 1 << ( opcode & 7 ) ) ) ) {
116
+ if ( ! ( cpu . data [ 95 ] & ( 1 << u8 ( opcode & 7 ) ) ) ) {
116
117
cpu . pc = cpu . pc + ( ( ( opcode & 0x1f8 ) >> 3 ) - ( opcode & 0x200 ? 0x40 : 0 ) ) ;
117
118
cpu . cycles ++ ;
118
119
}
119
120
} else if ( ( opcode & 0xfc00 ) === 0xf000 ) {
120
121
/* BRBS, 1111 00kk kkkk ksss */
121
- if ( cpu . data [ 95 ] & ( 1 << ( opcode & 7 ) ) ) {
122
+ if ( cpu . data [ 95 ] & ( 1 << u8 ( opcode & 7 ) ) ) {
122
123
cpu . pc = cpu . pc + ( ( ( opcode & 0x1f8 ) >> 3 ) - ( opcode & 0x200 ? 0x40 : 0 ) ) ;
123
124
cpu . cycles ++ ;
124
125
}
125
126
} else if ( ( opcode & 0xff8f ) === 0x9408 ) {
126
127
/* BSET, 1001 0100 0sss 1000 */
127
- cpu . data [ 95 ] |= 1 << ( ( opcode & 0x70 ) >> 4 ) ;
128
+ cpu . data [ 95 ] |= 1 << u8 ( ( opcode & 0x70 ) >> 4 ) ;
128
129
} else if ( ( opcode & 0xfe08 ) === 0xfa00 ) {
129
130
/* BST, 1111 101d dddd 0bbb */
130
131
const d = cpu . data [ ( opcode & 0x1f0 ) >> 4 ] ;
131
132
const b = opcode & 7 ;
132
- cpu . data [ 95 ] = ( cpu . data [ 95 ] & 0xbf ) | ( ( d >> b ) & 1 ? 0x40 : 0 ) ;
133
+ cpu . data [ 95 ] = ( cpu . data [ 95 ] & 0xbf ) | ( ( d >> u8 ( b ) ) & 1 ? 0x40 : 0 ) ;
133
134
} else if ( ( opcode & 0xfe0e ) === 0x940e ) {
134
135
/* CALL, 1001 010k kkkk 111k kkkk kkkk kkkk kkkk */
135
136
const k = cpu . progMem [ cpu . pc + 1 ] | ( ( opcode & 1 ) << 16 ) | ( ( opcode & 0x1f0 ) << 13 ) ;
136
137
const ret = cpu . pc + 2 ;
137
138
const sp = cpu . dataView . getUint16 ( 93 , true ) ;
138
- const { pc22Bits } = cpu ;
139
+ const pc22Bits = cpu . pc22Bits ;
139
140
cpu . data [ sp ] = 255 & ret ;
140
141
cpu . data [ sp - 1 ] = ( ret >> 8 ) & 255 ;
141
142
if ( pc22Bits ) {
@@ -146,10 +147,10 @@ export function avrInstruction(cpu: CPU) {
146
147
cpu . cycles += pc22Bits ? 4 : 3 ;
147
148
} else if ( ( opcode & 0xff00 ) === 0x9800 ) {
148
149
/* CBI, 1001 1000 AAAA Abbb */
149
- const A = opcode & 0xf8 ;
150
- const b = opcode & 7 ;
150
+ const A = u16 ( opcode ) & 0xf8 ;
151
+ const b = u8 ( opcode ) & 7 ;
151
152
const R = cpu . readData ( ( A >> 3 ) + 32 ) ;
152
- const mask = 1 << b ;
153
+ const mask : u8 = 1 << b ;
153
154
cpu . writeData ( ( A >> 3 ) + 32 , R & ~ mask , mask ) ;
154
155
} else if ( ( opcode & 0xfe0f ) === 0x9400 ) {
155
156
/* COM, 1001 010d dddd 0000 */
@@ -292,7 +293,7 @@ export function avrInstruction(cpu: CPU) {
292
293
/* ICALL, 1001 0101 0000 1001 */
293
294
const retAddr = cpu . pc + 1 ;
294
295
const sp = cpu . dataView . getUint16 ( 93 , true ) ;
295
- const { pc22Bits } = cpu ;
296
+ const pc22Bits = cpu . pc22Bits ;
296
297
cpu . data [ sp ] = retAddr & 255 ;
297
298
cpu . data [ sp - 1 ] = ( retAddr >> 8 ) & 255 ;
298
299
if ( pc22Bits ) {
@@ -307,7 +308,7 @@ export function avrInstruction(cpu: CPU) {
307
308
cpu . cycles ++ ;
308
309
} else if ( ( opcode & 0xf800 ) === 0xb000 ) {
309
310
/* IN, 1011 0AAd dddd AAAA */
310
- const i = cpu . readData ( ( ( opcode & 0xf ) | ( ( opcode & 0x600 ) >> 5 ) ) + 32 ) ;
311
+ const i = cpu . readData ( u16 ( ( opcode & 0xf ) | ( ( opcode & 0x600 ) >> 5 ) ) + 32 ) ;
311
312
cpu . data [ ( opcode & 0x1f0 ) >> 4 ] = i ;
312
313
} else if ( ( opcode & 0xfe0f ) === 0x9403 ) {
313
314
/* INC, 1001 010d dddd 0011 */
@@ -393,7 +394,7 @@ export function avrInstruction(cpu: CPU) {
393
394
cpu . cycles ++ ;
394
395
cpu . data [ ( opcode & 0x1f0 ) >> 4 ] = cpu . readData (
395
396
cpu . dataView . getUint16 ( 28 , true ) +
396
- ( ( opcode & 7 ) | ( ( opcode & 0xc00 ) >> 7 ) | ( ( opcode & 0x2000 ) >> 8 ) )
397
+ u16 ( ( opcode & 7 ) | ( ( opcode & 0xc00 ) >> 7 ) | ( ( opcode & 0x2000 ) >> 8 ) )
397
398
) ;
398
399
} else if ( ( opcode & 0xfe0f ) === 0x8000 ) {
399
400
/* LDZ, 1000 000d dddd 0000 */
@@ -419,7 +420,7 @@ export function avrInstruction(cpu: CPU) {
419
420
cpu . cycles ++ ;
420
421
cpu . data [ ( opcode & 0x1f0 ) >> 4 ] = cpu . readData (
421
422
cpu . dataView . getUint16 ( 30 , true ) +
422
- ( ( opcode & 7 ) | ( ( opcode & 0xc00 ) >> 7 ) | ( ( opcode & 0x2000 ) >> 8 ) )
423
+ u16 ( ( opcode & 7 ) | ( ( opcode & 0xc00 ) >> 7 ) | ( ( opcode & 0x2000 ) >> 8 ) )
423
424
) ;
424
425
} else if ( opcode === 0x95c8 ) {
425
426
/* LPM, 1001 0101 1100 1000 */
@@ -511,7 +512,10 @@ export function avrInstruction(cpu: CPU) {
511
512
cpu . data [ 95 ] = sreg ;
512
513
} else if ( ( opcode & 0xf800 ) === 0xb800 ) {
513
514
/* OUT, 1011 1AAr rrrr AAAA */
514
- cpu . writeData ( ( ( opcode & 0xf ) | ( ( opcode & 0x600 ) >> 5 ) ) + 32 , cpu . data [ ( opcode & 0x1f0 ) >> 4 ] ) ;
515
+ cpu . writeData (
516
+ u16 ( ( opcode & 0xf ) | ( ( opcode & 0x600 ) >> 5 ) ) + 32 ,
517
+ cpu . data [ ( opcode & 0x1f0 ) >> 4 ]
518
+ ) ;
515
519
} else if ( ( opcode & 0xfe0f ) === 0x900f ) {
516
520
/* POP, 1001 000d dddd 1111 */
517
521
const value = cpu . dataView . getUint16 ( 93 , true ) + 1 ;
@@ -529,7 +533,7 @@ export function avrInstruction(cpu: CPU) {
529
533
const k = ( opcode & 0x7ff ) - ( opcode & 0x800 ? 0x800 : 0 ) ;
530
534
const retAddr = cpu . pc + 1 ;
531
535
const sp = cpu . dataView . getUint16 ( 93 , true ) ;
532
- const { pc22Bits } = cpu ;
536
+ const pc22Bits = cpu . pc22Bits ;
533
537
cpu . data [ sp ] = 255 & retAddr ;
534
538
cpu . data [ sp - 1 ] = ( retAddr >> 8 ) & 255 ;
535
539
if ( pc22Bits ) {
@@ -540,7 +544,7 @@ export function avrInstruction(cpu: CPU) {
540
544
cpu . cycles += pc22Bits ? 3 : 2 ;
541
545
} else if ( opcode === 0x9508 ) {
542
546
/* RET, 1001 0101 0000 1000 */
543
- const { pc22Bits } = cpu ;
547
+ const pc22Bits = cpu . pc22Bits ;
544
548
const i = cpu . dataView . getUint16 ( 93 , true ) + ( pc22Bits ? 3 : 2 ) ;
545
549
cpu . dataView . setUint16 ( 93 , i , true ) ;
546
550
cpu . pc = ( cpu . data [ i - 1 ] << 8 ) + cpu . data [ i ] - 1 ;
@@ -550,7 +554,7 @@ export function avrInstruction(cpu: CPU) {
550
554
cpu . cycles += pc22Bits ? 4 : 3 ;
551
555
} else if ( opcode === 0x9518 ) {
552
556
/* RETI, 1001 0101 0001 1000 */
553
- const { pc22Bits } = cpu ;
557
+ const pc22Bits = cpu . pc22Bits ;
554
558
const i = cpu . dataView . getUint16 ( 93 , true ) + ( pc22Bits ? 3 : 2 ) ;
555
559
cpu . dataView . setUint16 ( 93 , i , true ) ;
556
560
cpu . pc = ( cpu . data [ i - 1 ] << 8 ) + cpu . data [ i ] - 1 ;
@@ -603,23 +607,23 @@ export function avrInstruction(cpu: CPU) {
603
607
cpu . data [ 95 ] = sreg ;
604
608
} else if ( ( opcode & 0xff00 ) === 0x9a00 ) {
605
609
/* SBI, 1001 1010 AAAA Abbb */
606
- const target = ( ( opcode & 0xf8 ) >> 3 ) + 32 ;
607
- const mask = 1 << ( opcode & 7 ) ;
610
+ const target = u16 ( ( opcode & 0xf8 ) >> 3 ) + 32 ;
611
+ const mask : u8 = 1 << u8 ( opcode & 7 ) ;
608
612
cpu . writeData ( target , cpu . readData ( target ) | mask , mask ) ;
609
613
cpu . cycles ++ ;
610
614
} else if ( ( opcode & 0xff00 ) === 0x9900 ) {
611
615
/* SBIC, 1001 1001 AAAA Abbb */
612
- const value = cpu . readData ( ( ( opcode & 0xf8 ) >> 3 ) + 32 ) ;
613
- if ( ! ( value & ( 1 << ( opcode & 7 ) ) ) ) {
616
+ const value = cpu . readData ( u16 ( ( opcode & 0xf8 ) >> 3 ) + 32 ) ;
617
+ if ( ! ( value & ( 1 << u8 ( opcode & 7 ) ) ) ) {
614
618
const nextOpcode = cpu . progMem [ cpu . pc + 1 ] ;
615
619
const skipSize = isTwoWordInstruction ( nextOpcode ) ? 2 : 1 ;
616
620
cpu . cycles += skipSize ;
617
621
cpu . pc += skipSize ;
618
622
}
619
623
} else if ( ( opcode & 0xff00 ) === 0x9b00 ) {
620
624
/* SBIS, 1001 1011 AAAA Abbb */
621
- const value = cpu . readData ( ( ( opcode & 0xf8 ) >> 3 ) + 32 ) ;
622
- if ( value & ( 1 << ( opcode & 7 ) ) ) {
625
+ const value = cpu . readData ( u16 ( ( opcode & 0xf8 ) >> 3 ) + 32 ) ;
626
+ if ( value & ( 1 << u8 ( opcode & 7 ) ) ) {
623
627
const nextOpcode = cpu . progMem [ cpu . pc + 1 ] ;
624
628
const skipSize = isTwoWordInstruction ( nextOpcode ) ? 2 : 1 ;
625
629
cpu . cycles += skipSize ;
@@ -629,7 +633,7 @@ export function avrInstruction(cpu: CPU) {
629
633
/* SBIW, 1001 0111 KKdd KKKK */
630
634
const i = 2 * ( ( opcode & 0x30 ) >> 4 ) + 24 ;
631
635
const a = cpu . dataView . getUint16 ( i , true ) ;
632
- const l = ( opcode & 0xf ) | ( ( opcode & 0xc0 ) >> 2 ) ;
636
+ const l = u16 ( ( opcode & 0xf ) | ( ( opcode & 0xc0 ) >> 2 ) ) ;
633
637
const R = a - l ;
634
638
cpu . dataView . setUint16 ( i , R , true ) ;
635
639
let sreg = cpu . data [ 95 ] & 0xc0 ;
@@ -643,15 +647,15 @@ export function avrInstruction(cpu: CPU) {
643
647
cpu . cycles ++ ;
644
648
} else if ( ( opcode & 0xfe08 ) === 0xfc00 ) {
645
649
/* SBRC, 1111 110r rrrr 0bbb */
646
- if ( ! ( cpu . data [ ( opcode & 0x1f0 ) >> 4 ] & ( 1 << ( opcode & 7 ) ) ) ) {
650
+ if ( ! ( cpu . data [ ( opcode & 0x1f0 ) >> 4 ] & ( 1 << u8 ( opcode & 7 ) ) ) ) {
647
651
const nextOpcode = cpu . progMem [ cpu . pc + 1 ] ;
648
652
const skipSize = isTwoWordInstruction ( nextOpcode ) ? 2 : 1 ;
649
653
cpu . cycles += skipSize ;
650
654
cpu . pc += skipSize ;
651
655
}
652
656
} else if ( ( opcode & 0xfe08 ) === 0xfe00 ) {
653
657
/* SBRS, 1111 111r rrrr 0bbb */
654
- if ( cpu . data [ ( opcode & 0x1f0 ) >> 4 ] & ( 1 << ( opcode & 7 ) ) ) {
658
+ if ( cpu . data [ ( opcode & 0x1f0 ) >> 4 ] & ( 1 << u8 ( opcode & 7 ) ) ) {
655
659
const nextOpcode = cpu . progMem [ cpu . pc + 1 ] ;
656
660
const skipSize = isTwoWordInstruction ( nextOpcode ) ? 2 : 1 ;
657
661
cpu . cycles += skipSize ;
@@ -715,7 +719,7 @@ export function avrInstruction(cpu: CPU) {
715
719
/* STDY, 10q0 qq1r rrrr 1qqq */
716
720
cpu . writeData (
717
721
cpu . dataView . getUint16 ( 28 , true ) +
718
- ( ( opcode & 7 ) | ( ( opcode & 0xc00 ) >> 7 ) | ( ( opcode & 0x2000 ) >> 8 ) ) ,
722
+ u16 ( ( opcode & 7 ) | ( ( opcode & 0xc00 ) >> 7 ) | ( ( opcode & 0x2000 ) >> 8 ) ) ,
719
723
cpu . data [ ( opcode & 0x1f0 ) >> 4 ]
720
724
) ;
721
725
cpu . cycles ++ ;
@@ -743,7 +747,7 @@ export function avrInstruction(cpu: CPU) {
743
747
/* STDZ, 10q0 qq1r rrrr 0qqq */
744
748
cpu . writeData (
745
749
cpu . dataView . getUint16 ( 30 , true ) +
746
- ( ( opcode & 7 ) | ( ( opcode & 0xc00 ) >> 7 ) | ( ( opcode & 0x2000 ) >> 8 ) ) ,
750
+ u16 ( ( opcode & 7 ) | ( ( opcode & 0xc00 ) >> 7 ) | ( ( opcode & 0x2000 ) >> 8 ) ) ,
747
751
cpu . data [ ( opcode & 0x1f0 ) >> 4 ]
748
752
) ;
749
753
cpu . cycles ++ ;
0 commit comments