Initial commit (a clone of the jsmachines project as of v1.15.3)

This commit is contained in:
jeffpar 2014-09-27 14:52:57 -07:00
commit a5e3e6a59d
714 changed files with 130602 additions and 0 deletions

View file

@ -0,0 +1,476 @@
.0200/A0
01
8C
CE
03
A9
00
8D
D1
03
8D
D4
03
AD
D4
03
02
01
54
65
73
74
69
6E
67
20
25
41
00
29
0F
8D
D5
03
AD
D4
03
29
F0
8D
D9
03
09
0F
8D
DA
03
AD
D1
03
29
0F
8D
D3
03
AD
D1
03
29
F0
8D
D2
03
20
79
02
20
62
03
20
33
03
D0
26
20
CC
02
20
6F
03
20
33
03
D0
1B
EE
D1
03
D0
D5
EE
D4
03
D0
AE
88
10
AB
A9
00
8D
CE
03
02
01
50
41
53
53
00
F0
07
02
01
46
41
49
4C
00
02
00
F8
C0
01
AD
D1
03
6D
D4
03
8D
CC
03
08
68
8D
CD
03
D8
C0
01
AD
D1
03
6D
D4
03
8D
CF
03
08
68
8D
D0
03
C0
01
AD
D3
03
6D
D5
03
C9
0A
A2
00
90
06
E8
69
05
29
0F
38
0D
D2
03
7D
D9
03
08
B0
04
C9
A0
90
03
69
5F
38
8D
CA
03
08
68
8D
CB
03
68
8D
D7
03
60
F8
C0
01
AD
D1
03
ED
D4
03
8D
CC
03
08
68
8D
CD
03
D8
C0
01
AD
D1
03
ED
D4
03
8D
CF
03
08
68
8D
D0
03
60
C0
01
AD
D3
03
ED
D5
03
A2
00
B0
06
E8
E9
05
29
0F
18
0D
D2
03
FD
D9
03
B0
02
E9
5F
8D
CA
03
60
C0
01
AD
D3
03
ED
D5
03
A2
00
B0
04
E8
29
0F
18
0D
D2
03
FD
D9
03
B0
02
E9
5F
E0
00
F0
02
E9
06
8D
CA
03
60
AD
CC
03
CD
CA
03
D0
26
AD
CD
03
4D
D6
03
29
80
D0
1C
AD
CD
03
4D
D7
03
29
40
D0
12
AD
CD
03
4D
D8
03
29
02
D0
08
AD
CD
03
4D
CB
03
29
01
60
AD
D7
03
8D
D6
03
AD
D0
03
8D
D8
03
60
20
EF
02
AD
D0
03
8D
D6
03
8D
D7
03
8D
D8
03
8D
CB
03
60
AD
CA
03
08
68
8D
D6
03
8D
D8
03
60
20
0F
03
AD
CA
03
08
68
8D
D6
03
8D
D8
03
AD
D0
03
8D
D7
03
8D
CB
03
60
AD
CA
03
08
68
8D
D6
03
8D
D8
03
60
20
EF
02
AD
CA
03
08
68
8D
D6
03
8D
D8
03
AD
D0
03
8D
D7
03
8D
CB
03
60
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
.0200G

View file

@ -0,0 +1,332 @@
;
; The following code comes from:
;
; http://www.6502.org/tutorials/decimal_mode.html
;
; and is built with:
;
; ca65 bcd.asm -I ../.. -l -o bcd.obj
; ld65 bcd.obj -o bcd.bin --target none
;
; An ASCII hex file which the OSI machine-language monitor can load
; is produced with the following commands:
;
; echo -n ".0200/" > bcd.txt
; hexdump -e '1/1 "%02X\n"' -v bcd.bin >> bcd.txt
; echo -n ".0200" >> bcd.txt
;
.include "sim.inc"
VALID_BCD_ONLY = 0
VALID_FLAGS_ONLY = 0
;
; Verify decimal mode behavior
;
; Returns:
; ERROR = 0 if the test passed
; ERROR = 1 if the test failed
;
; This routine requires 17 bytes of RAM -- 1 byte each for:
; AR, CF, DA, DNVZC, ERROR, HA, HNVZC, N1, N1H, N1L, N2, N2L, NF, VF, and ZF
; and 2 bytes for N2H
;
; Variables:
; N1 and N2 are the two numbers to be added or subtracted
; N1H, N1L, N2H, and N2L are the upper 4 bits and lower 4 bits of N1 and N2
; DA and DNVZC are the actual accumulator and flag results in decimal mode
; HA and HNVZC are the accumulator and flag results when N1 and N2 are
; added or subtracted using binary arithmetic
; AR, NF, VF, ZF, and CF are the predicted decimal mode accumulator and
; flag results, calculated using binary arithmetic
;
; This program takes approximately 1 minute at 1 MHz (a few seconds more on
; a 65C02 than a 6502 or 65816)
;
TEST: LDY #1 ; initialize Y (used to loop through carry flag values)
STY ERROR ; store 1 in ERROR until the test passes
LDA #0 ; initialize N1 and N2
STA N1
STA N2
LOOP1: LDA N2 ; N2L = N2 & $0F
SIM_MSG "Testing %A"
AND #$0F ; [1] see text
.if VALID_BCD_ONLY <> 0
CMP #$0A
BCS NEXT2
.endif
STA N2L
LDA N2 ; N2H = N2 & $F0
AND #$F0 ; [2] see text
.if VALID_BCD_ONLY <> 0
CMP #$A0
BCS NEXT2
.endif
STA N2H
ORA #$0F ; N2H+1 = (N2 & $F0) + $0F
STA N2H+1
LOOP2: LDA N1 ; N1L = N1 & $0F
;; SIM_MSG " with %A"
AND #$0F ; [3] see text
.if VALID_BCD_ONLY <> 0
CMP #$0A
BCS NEXT1
.endif
STA N1L
LDA N1 ; N1H = N1 & $F0
AND #$F0 ; [4] see text
.if VALID_BCD_ONLY <> 0
CMP #$A0
BCS NEXT1
.endif
STA N1H
JSR ADD
JSR A6502
JSR COMPARE
BNE ERR
JSR SUB
JSR S6502
JSR COMPARE
BNE ERR
NEXT1: INC N1 ; [5] see text
BNE LOOP2 ; loop through all 256 values of N1
NEXT2: INC N2 ; [6] see text
BNE LOOP1 ; loop through all 256 values of N2
DEY
BPL LOOP1 ; loop through both values of the carry flag
LDA #0 ; test passed, so store 0 in ERROR
STA ERROR
SIM_MSG "PASS"
BEQ DONE
ERR: SIM_MSG "FAIL"
DONE: SIM_HLT
; Calculate the actual decimal mode accumulator and flags, the accumulator
; and flag results when N1 is added to N2 using binary arithmetic, the
; predicted accumulator result, the predicted carry flag, and the predicted
; V flag
;
ADD: SED ; decimal mode
CPY #1 ; set carry if Y = 1, clear carry if Y = 0
LDA N1
ADC N2
STA DA ; actual accumulator result in decimal mode
PHP
PLA
STA DNVZC ; actual flags result in decimal mode
CLD ; binary mode
CPY #1 ; set carry if Y = 1, clear carry if Y = 0
LDA N1
ADC N2
STA HA ; accumulator result of N1+N2 using binary arithmetic
PHP
PLA
STA HNVZC ; flags result of N1+N2 using binary arithmetic
CPY #1
LDA N1L
ADC N2L
CMP #$0A
LDX #0
BCC A1
INX
ADC #5 ; add 6 (carry is set)
AND #$0F
SEC
A1: ORA N1H
;
; if N1L + N2L < $0A, then add N2 & $F0
; if N1L + N2L >= $0A, then add (N2 & $F0) + $0F + 1 (carry is set)
;
ADC N2H,X
PHP
BCS A2
CMP #$A0
BCC A3
A2: ADC #$5F ; add $60 (carry is set)
SEC
A3: STA AR ; predicted accumulator result
PHP
PLA
STA CF ; predicted carry result
PLA
;
; note that all 8 bits of the P register are stored in VF
;
STA VF ; predicted V flags
RTS
; Calculate the actual decimal mode accumulator and flags, and the
; accumulator and flag results when N2 is subtracted from N1 using binary
; arithmetic
;
SUB: SED ; decimal mode
CPY #1 ; set carry if Y = 1, clear carry if Y = 0
LDA N1
SBC N2
STA DA ; actual accumulator result in decimal mode
PHP
PLA
STA DNVZC ; actual flags result in decimal mode
CLD ; binary mode
CPY #1 ; set carry if Y = 1, clear carry if Y = 0
LDA N1
SBC N2
STA HA ; accumulator result of N1-N2 using binary arithmetic
PHP
PLA
STA HNVZC ; flags result of N1-N2 using binary arithmetic
RTS
; Calculate the predicted SBC accumulator result for the 6502 and 65816
;
SUB1: CPY #1 ; set carry if Y = 1, clear carry if Y = 0
LDA N1L
SBC N2L
LDX #0
BCS S11
INX
SBC #5 ; subtract 6 (carry is clear)
AND #$0F
CLC
S11: ORA N1H
;
; if N1L - N2L >= 0, then subtract N2 & $F0
; if N1L - N2L < 0, then subtract (N2 & $F0) + $0F + 1 (carry is clear)
;
SBC N2H,X
BCS S12
SBC #$5F ; subtract $60 (carry is clear)
S12: STA AR
RTS
; Calculate the predicted SBC accumulator result for the 6502 and 65C02
;
SUB2: CPY #1 ; set carry if Y = 1, clear carry if Y = 0
LDA N1L
SBC N2L
LDX #0
BCS S21
INX
AND #$0F
CLC
S21: ORA N1H
;
; if N1L - N2L >= 0, then subtract N2 & $F0
; if N1L - N2L < 0, then subtract (N2 & $F0) + $0F + 1 (carry is clear)
;
SBC N2H,X
BCS S22
SBC #$5F ; subtract $60 (carry is clear)
S22: CPX #0
BEQ S23
SBC #6
S23: STA AR ; predicted accumulator result
RTS
; Compare accumulator actual results to predicted results
;
; Return:
; Z flag = 1 (BEQ branch) if same
; Z flag = 0 (BNE branch) if different
;
COMPARE:LDA DA
CMP AR
BNE C1
.if VALID_FLAGS_ONLY = 0
LDA DNVZC ; [7] see text
EOR NF
AND #$80 ; mask off N flag
BNE C1
LDA DNVZC ; [8] see text
EOR VF
AND #$40 ; mask off V flag
BNE C1 ; [9] see text
LDA DNVZC
EOR ZF ; mask off Z flag
AND #2
BNE C1 ; [10] see text
.endif
LDA DNVZC
EOR CF
AND #1 ; mask off C flag
C1: RTS
; These routines store the predicted values for ADC and SBC for the 6502,
; 65C02, and 65816 in AR, CF, NF, VF, and ZF
A6502: LDA VF
;
; since all 8 bits of the P register were stored in VF, bit 7 of VF contains
; the N flag for NF
;
STA NF
LDA HNVZC
STA ZF
RTS
S6502: JSR SUB1
LDA HNVZC
STA NF
STA VF
STA ZF
STA CF
RTS
A65C02: LDA AR
PHP
PLA
STA NF
STA ZF
RTS
S65C02: JSR SUB2
LDA AR
PHP
PLA
STA NF
STA ZF
LDA HNVZC
STA VF
STA CF
RTS
A65816: LDA AR
PHP
PLA
STA NF
STA ZF
RTS
S65816: JSR SUB1
LDA AR
PHP
PLA
STA NF
STA ZF
LDA HNVZC
STA VF
STA CF
RTS
.data
AR: .byte 0
CF: .byte 0 ; predicted carry result
DA: .byte 0
DNVZC: .byte 0
ERROR: .byte 0
HA: .byte 0
HNVZC: .byte 0
N1: .byte 0
N1H: .byte 0
N1L: .byte 0
N2: .byte 0
N2L: .byte 0
NF: .byte 0
VF: .byte 0
ZF: .byte 0
N2H: .word 0

View file

@ -0,0 +1,19 @@
CA65 = ca65
LD65 = ld65
ECHO = @/bin/echo
CA65_OPTS =
LD65_OPTS = --target none
all: bcd.65v
bcd.obj: bcd.asm
$(CA65) bcd.asm -I ../.. -l -o bcd.obj
bcd.bin: bcd.obj
$(LD65) $(LD65_OPTS) $+ -o $@
bcd.65v: bcd.bin
$(ECHO) -n ".0200/" > bcd.65v
hexdump -e '1/1 "%02X\n"' -v bcd.bin >> bcd.65v
$(ECHO) -n ".0200G" >> bcd.65v

View file

@ -0,0 +1,19 @@
CA65 = ca65
LD65 = ld65
ECHO = @/bin/echo
CA65_OPTS =
LD65_OPTS = --target none
all: vflag.65v
vflag.obj: vflag.asm
$(CA65) vflag.asm -I ../.. -l -o vflag.obj
vflag.bin: vflag.obj
$(LD65) $(LD65_OPTS) $+ -o $@
vflag.65v: vflag.bin
$(ECHO) -n ".0200/" > vflag.65v
hexdump -e '1/1 "%02X\n"' -v vflag.bin >> vflag.65v
$(ECHO) -n ".0200G" >> vflag.65v

View file

@ -0,0 +1,159 @@
.0200/D8
A9
01
8D
99
02
A9
80
8D
9A
02
8D
9B
02
A9
00
8D
9C
02
8D
9D
02
A0
01
20
50
02
E0
01
F0
28
20
6F
02
E0
01
F0
21
EE
9A
02
EE
9C
02
D0
EA
EE
9B
02
EE
9D
02
D0
E2
88
10
DF
A9
00
8D
99
02
02
01
50
41
53
53
00
F0
07
02
01
46
41
49
4C
00
02
00
C0
01
AD
9A
02
6D
9B
02
A2
00
50
01
E8
C0
01
AD
9C
02
6D
9D
02
B0
04
30
01
E8
60
10
01
E8
60
C0
01
AD
9A
02
ED
9B
02
A2
00
50
01
E8
C0
01
AD
9C
02
ED
9D
02
48
A9
FF
E9
00
C9
FE
D0
05
68
30
01
E8
60
68
90
FB
10
01
E8
60
00
00
00
00
00
.0200G

View file

@ -0,0 +1,124 @@
;
; The following code comes from:
;
; http://www.6502.org/tutorials/vflag.html
;
; and is built with:
;
; ca65 vflag.asm -I ../.. -l -o vflag.obj
; ld65 vflag.obj -o vflag.bin --target none
;
; An ASCII hex file which the OSI machine-language monitor can load
; is produced with the following commands:
;
; echo -n ".0200/" > vflag.txt
; hexdump -e '1/1 "%02X\n"' -v vflag.bin >> vflag.txt
; echo -n ".0200" >> vflag.txt
;
.include "sim.inc"
; Demonstrate that the V flag works as described
;
; Returns with ERROR = 0 if the test passes, ERROR = 1 if the test fails
;
; Five (additional) memory locations are used: ERROR, S1, S2, U1, and U2
; which can be located anywhere convenient in RAM
;
; The program below takes about 16 seconds to complete at 1 MHz.
;
TEST: CLD ; Clear decimal mode (just in case) for test
LDA #1
STA ERROR ; Store 1 in ERROR until test passes
LDA #$80
STA S1 ; Initalize S1 and S2 to -128 ($80)
STA S2
LDA #0
STA U1 ; Initialize U1 and U2 to 0
STA U2
LDY #1 ; Initialize Y (used to set and clear the carry flag) to 1
LOOP: JSR ADD ; Test ADC
CPX #1
BEQ ERR ; End if V and unsigned result do not agree (X = 1)
JSR SUB ; Test SBC
CPX #1
BEQ ERR ; End if V and unsigned result do not agree (X = 1)
INC S1
INC U1
BNE LOOP ; Loop until all 256 possibilities of S1 and U1 are tested
INC S2
INC U2
BNE LOOP ; Loop until all 256 possibilities of S2 and U2 are tested
DEY
BPL LOOP ; Loop until both possiblities of the carry flag are tested
LDA #0
STA ERROR ; All tests pass, so store 0 in ERROR
SIM_MSG "PASS"
BEQ DONE
ERR: SIM_MSG "FAIL"
DONE: SIM_HLT
;
; Test ADC
;
; X is initialized to 0
; X is incremented when V = 1
; X is incremented when the unsigned result predicts an overflow
; Therefore, if the V flag and the unsigned result agree, X will be
; incremented zero or two times (returning X = 0 or X = 2), and if they do
; not agree X will be incremented once (returning X = 1)
;
ADD: CPY #1 ; Set carry when Y = 1, clear carry when Y = 0
LDA S1 ; Test twos complement addition
ADC S2
LDX #0 ; Initialize X to 0
BVC ADD1
INX ; Increment X if V = 1
ADD1: CPY #1 ; Set carry when Y = 1, clear carry when Y = 0
LDA U1 ; Test unsigned addition
ADC U2
BCS ADD3 ; Carry is set if U1 + U2 >= 256
BMI ADD2 ; U1 + U2 < 256, A >= 128 if U1 + U2 >= 128
INX ; Increment X if U1 + U2 < 128
ADD2: RTS
ADD3: BPL ADD4 ; U1 + U2 >= 256, A <= 127 if U1 + U2 <= 383 ($17F)
INX ; Increment X if U1 + U2 > 383
ADD4: RTS
;
; Test SBC
;
; X is initialized to 0
; X is incremented when V = 1
; X is incremented when the unsigned result predicts an overflow
; Therefore, if the V flag and the unsigned result agree, X will be
; incremented zero or two times (returning X = 0 or X = 2), and if they do
; not agree X will be incremented once (returning X = 1)
;
SUB: CPY #1 ; Set carry when Y = 1, clear carry when Y = 0
LDA S1 ; Test twos complement subtraction
SBC S2
LDX #0 ; Initialize X to 0
BVC SUB1
INX ; Increment X if V = 1
SUB1: CPY #1 ; Set carry when Y = 1, clear carry when Y = 0
LDA U1 ; Test unsigned subtraction
SBC U2
PHA ; Save the low byte of result on the stack
LDA #$FF
SBC #$00 ; result = (65280 + U1) - U2, 65280 = $FF00
CMP #$FE
BNE SUB4 ; Branch if result >= 65280 ($FF00) or result < 65024 ($FE00)
PLA ; Get the low byte of result
BMI SUB3 ; result < 65280 ($FF00), A >= 128 if result >= 65152 ($FE80)
SUB2: INX ; Increment X if result < 65152 ($FE80)
SUB3: RTS
SUB4: PLA ; Get the low byte of result (does not affect the carry flag)
BCC SUB2 ; The carry flag is clear if result < 65024 ($FE00)
BPL SUB5 ; result >= 65280 ($FF00), A <= 127 if result <= 65407 ($FF7F)
INX ; Increment X if result > 65407 ($FF7F)
SUB5: RTS
.data
ERROR: .byte 0
S1: .byte 0
S2: .byte 0
U1: .byte 0
U2: .byte 0