@@ -4,107 +4,151 @@ import * as utils from "../utils.js";
4
4
import { fake6502 } from "../fake6502.js" ;
5
5
6
6
const processor = fake6502 ( ) ;
7
- const irqRoutine = [
8
- 0x48 , 0x8a , 0x48 , 0x98 , 0x48 , 0xba , 0xbd , 0x04 , 0x01 , 0x29 , 0x10 , 0xf0 , 0x03 , 0x6c , 0x16 , 0x03 , 0x6c , 0x14 , 0x03 ,
7
+ const IRQ_ROUTINE_START = 0xff48 ;
8
+ const RTS_OPCODE = 0x60 ;
9
+ const NOP_OPCODE = 0xea ;
10
+ const IRQ_ROUTINE = [
11
+ 0x48 , // PHA
12
+ 0x8a , // TXA
13
+ 0x48 , // PHA
14
+ 0x98 , // TYA
15
+ 0x48 , // PHA
16
+ 0xba , // TSX
17
+ 0xbd ,
18
+ 0x04 ,
19
+ 0x01 , // LDA $0104,X
20
+ 0x29 ,
21
+ 0x10 , // AND #$10
22
+ 0xf0 ,
23
+ 0x03 , // BEQ $03
24
+ 0x6c ,
25
+ 0x16 ,
26
+ 0x03 , // JMP ($0316)
27
+ 0x6c ,
28
+ 0x14 ,
29
+ 0x03 , // JMP ($0314)
9
30
] ;
10
31
11
- function setup ( filename ) {
32
+ async function setup ( filename ) {
33
+ try {
34
+ initializeMemory ( ) ;
35
+ await loadTest ( filename ) ;
36
+ setupIRQRoutine ( ) ;
37
+ setupProcessor ( ) ;
38
+ } catch ( error ) {
39
+ console . error ( `Error in setup: ${ error . message } ` ) ;
40
+ }
41
+ }
42
+
43
+ function initializeMemory ( ) {
12
44
for ( let i = 0x0000 ; i < 0xffff ; ++ i ) processor . writemem ( i , 0x00 ) ;
13
- return utils . loadData ( "tests/suite/bin/" + filename ) . then ( function ( data ) {
14
- const addr = data [ 0 ] + ( data [ 1 ] << 8 ) ;
15
- console . log ( ">> Loading test '" + filename + "' at " + utils . hexword ( addr ) ) ;
16
- for ( let i = 2 ; i < data . length ; ++ i ) processor . writemem ( addr + i - 2 , data [ i ] ) ;
17
- for ( let i = 0 ; i < irqRoutine . length ; ++ i ) processor . writemem ( 0xff48 + i , irqRoutine [ i ] ) ;
18
-
19
- processor . writemem ( 0x0002 , 0x00 ) ;
20
- processor . writemem ( 0xa002 , 0x00 ) ;
21
- processor . writemem ( 0xa003 , 0x80 ) ; // Docs say put zero here, but this works better.
22
- processor . writemem ( 0x01fe , 0xff ) ;
23
- processor . writemem ( 0x01ff , 0x7f ) ;
24
-
25
- // Put RTSes in some of the stubbed calls
26
- processor . writemem ( 0xffd2 , 0x60 ) ;
27
- processor . writemem ( 0x8000 , 0x60 ) ;
28
- processor . writemem ( 0xa474 , 0x60 ) ;
29
- // NOP the loading routine
30
- processor . writemem ( 0xe16f , 0xea ) ;
31
- // scan keyboard is LDA #3: RTS
32
- processor . writemem ( 0xffe4 , 0xa9 ) ;
33
- processor . writemem ( 0xffe5 , 0x03 ) ;
34
- processor . writemem ( 0xffe6 , 0x60 ) ;
35
- processor . writemem ( 0xfffe , 0x48 ) ;
36
- processor . writemem ( 0xffff , 0xff ) ;
37
-
38
- processor . s = 0xfd ;
39
- processor . p . reset ( ) ;
40
- processor . p . i = true ;
41
- processor . pc = 0x0801 ;
42
- } ) ;
45
+ }
46
+
47
+ async function loadTest ( filename ) {
48
+ const data = await utils . loadData ( `tests/suite/bin/${ filename } ` ) ;
49
+ const addr = data [ 0 ] + ( data [ 1 ] << 8 ) ;
50
+ console . log ( `>> Loading test '${ filename } ' at ${ utils . hexword ( addr ) } ` ) ;
51
+ for ( let i = 2 ; i < data . length ; ++ i ) processor . writemem ( addr + i - 2 , data [ i ] ) ;
52
+ }
53
+
54
+ function setupIRQRoutine ( ) {
55
+ for ( let i = 0 ; i < IRQ_ROUTINE . length ; ++ i ) processor . writemem ( IRQ_ROUTINE_START + i , IRQ_ROUTINE [ i ] ) ;
56
+ }
57
+
58
+ function setupProcessor ( ) {
59
+ processor . writemem ( 0x0002 , 0x00 ) ;
60
+ processor . writemem ( 0xa002 , 0x00 ) ;
61
+ processor . writemem ( 0xa003 , 0x80 ) ;
62
+ processor . writemem ( 0x01fe , 0xff ) ;
63
+ processor . writemem ( 0x01ff , 0x7f ) ;
64
+ processor . writemem ( 0xffd2 , RTS_OPCODE ) ;
65
+ processor . writemem ( 0x8000 , RTS_OPCODE ) ;
66
+ processor . writemem ( 0xa474 , RTS_OPCODE ) ;
67
+ processor . writemem ( 0xe16f , NOP_OPCODE ) ;
68
+ processor . writemem ( 0xffe4 , 0xa9 ) ;
69
+ processor . writemem ( 0xffe5 , 0x03 ) ;
70
+ processor . writemem ( 0xffe6 , RTS_OPCODE ) ;
71
+ processor . writemem ( 0xfffe , 0x48 ) ;
72
+ processor . writemem ( 0xffff , 0xff ) ;
73
+ processor . s = 0xfd ;
74
+ processor . p . reset ( ) ;
75
+ processor . p . i = true ;
76
+ processor . pc = 0x0801 ;
43
77
}
44
78
45
79
let curLine = "" ;
46
80
47
81
function petToAscii ( char ) {
48
- if ( char === 14 ) return "" ; // text mode
49
- if ( char === 145 ) return "" ; // up arrow
50
- if ( char === 147 ) return "\n-------\n" ; // Clear
51
- if ( char >= 0xc1 && char <= 0xda ) char = char - 0xc1 + 65 ;
52
- else if ( char >= 0x41 && char <= 0x5a ) char = char - 0x41 + 97 ;
53
- else if ( char < 32 || char >= 127 ) {
54
- char = 46 ;
55
- }
82
+ if ( char === 14 || char === 145 ) return "" ;
83
+ if ( char === 147 ) return "\n-------\n" ;
84
+ if ( char >= 0xc1 && char <= 0xda ) return String . fromCharCode ( char - 0xc1 + 65 ) ;
85
+ if ( char >= 0x41 && char <= 0x5a ) return String . fromCharCode ( char - 0x41 + 97 ) ;
86
+ if ( char < 32 || char >= 127 ) return "." ;
56
87
return String . fromCharCode ( char ) ;
57
88
}
58
89
59
- processor . debugInstruction . add ( function ( addr ) {
90
+ processor . debugInstruction . add ( ( addr ) => {
60
91
switch ( addr ) {
61
92
case 0xffd2 :
62
- if ( processor . a === 13 ) {
63
- console . log ( curLine ) ;
64
- curLine = "" ;
65
- } else {
66
- curLine += petToAscii ( processor . a ) ;
67
- }
68
- processor . writemem ( 0x030c , 0x00 ) ;
93
+ handlePrint ( ) ;
69
94
break ;
70
- case 0xe16f : {
71
- const filenameAddr = processor . readmem ( 0xbb ) | ( processor . readmem ( 0xbc ) << 8 ) ;
72
- const filenameLen = processor . readmem ( 0xb7 ) ;
73
- let filename = "" ;
74
- for ( let i = 0 ; i < filenameLen ; ++ i ) filename += petToAscii ( processor . readmem ( filenameAddr + i ) ) ;
75
- if ( filename === "trap17" ) {
76
- console . log ( "All tests complete" ) ;
77
- process . exit ( 0 ) ;
78
- }
79
-
80
- setup ( filename ) . then ( anIter ) ;
81
- processor . pc -- ; // Account for the instruction fetch
82
- return true ; // Break out of the 'anIter' loop
83
- }
95
+ case 0xe16f :
96
+ handleLoad ( ) ;
97
+ return true ;
84
98
case 0x8000 :
85
- case 0xa474 : // Fail
86
- if ( curLine . length ) console . log ( curLine ) ;
87
- throw "Test failed" ;
88
-
99
+ case 0xa474 :
100
+ handleError ( ) ;
101
+ break ;
89
102
default :
90
103
break ;
91
104
}
92
105
return false ;
93
106
} ) ;
94
107
108
+ function handlePrint ( ) {
109
+ if ( processor . a === 13 ) {
110
+ console . log ( curLine ) ;
111
+ curLine = "" ;
112
+ } else {
113
+ curLine += petToAscii ( processor . a ) ;
114
+ }
115
+ processor . writemem ( 0x030c , 0x00 ) ;
116
+ }
117
+
118
+ function handleLoad ( ) {
119
+ const filenameAddr = processor . readmem ( 0xbb ) | ( processor . readmem ( 0xbc ) << 8 ) ;
120
+ const filenameLen = processor . readmem ( 0xb7 ) ;
121
+ let filename = "" ;
122
+ for ( let i = 0 ; i < filenameLen ; ++ i ) filename += petToAscii ( processor . readmem ( filenameAddr + i ) ) ;
123
+ if ( filename === "trap17" ) {
124
+ console . log ( "All tests complete" ) ;
125
+ process . exit ( 0 ) ;
126
+ }
127
+ setup ( filename ) . then ( anIter ) ;
128
+ processor . pc -- ;
129
+ return true ;
130
+ }
131
+
132
+ function handleError ( ) {
133
+ if ( curLine . length ) console . log ( curLine ) ;
134
+ throw new Error ( "Test failed" ) ;
135
+ }
136
+
95
137
function anIter ( ) {
96
138
for ( ; ; ) {
97
139
if ( ! processor . execute ( 10 * 1000 * 1000 ) ) return ;
98
140
}
99
141
}
100
142
101
- processor
102
- . initialise ( )
103
- . then ( function ( ) {
104
- if ( process . argv . length === 3 ) {
105
- return setup ( process . argv [ 2 ] ) ;
106
- } else {
107
- return setup ( " start" ) ;
108
- }
109
- } )
110
- . then ( anIter ) ;
143
+ async function main ( ) {
144
+ try {
145
+ await processor . initialise ( ) ;
146
+ const filename = process . argv . length === 3 ? process . argv [ 2 ] : " start" ;
147
+ await setup ( filename ) ;
148
+ anIter ( ) ;
149
+ } catch ( error ) {
150
+ console . error ( `Error in main: ${ error . message } ` ) ;
151
+ }
152
+ }
153
+
154
+ main ( ) . then ( ( ) => { } ) ;
0 commit comments