Add additional pass that writes values based on memory address
This commit is contained in:
parent
eec3b750bb
commit
27934ac541
4 changed files with 96 additions and 62 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,3 +1,3 @@
|
||||||
emu6502
|
emu6502
|
||||||
*.o
|
*.o65
|
||||||
*.bin
|
*.bin
|
24
Makefile
24
Makefile
|
@ -1,25 +1,25 @@
|
||||||
|
|
||||||
.PHONY: all memtest-f000.901465.bin memtest-f000.901465.o ascii memtest-f000.901465+ascii.o emu5602
|
.PHONY: all memtest-f000.901465.bin memtest-f000.901465.o65 ascii memtest-f000.901465+ascii.o65 emu5602
|
||||||
|
|
||||||
all: memtest-f000.901465.bin ascii emu5602
|
all: memtest-f000.901465.bin ascii emu5602
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f memtest-f000.901465.bin memtest-f000.901465.o
|
rm -f memtest-f000.901465.bin memtest-f000.901465.o65 memtest-f000.901465.map
|
||||||
rm -f memtest-f000.901465+ascii.bin memtest-f000.901465+ascii.o
|
rm -f memtest-f000.901465+ascii.bin memtest-f000.901465+ascii.o65 memtest-f000.901465+ascii.map
|
||||||
rm -f emu6502
|
rm -f emu6502
|
||||||
|
|
||||||
memtest-f000.901465.bin: memtest-f000.901465.o
|
memtest-f000.901465.bin: memtest-f000.901465.o65
|
||||||
dd if=memtest-f000.901465.o bs=1 skip=2 of=memtest-f000.901465.bin
|
dd if=memtest-f000.901465.o65 bs=1 skip=2 of=memtest-f000.901465.bin
|
||||||
|
|
||||||
memtest-f000.901465.o:
|
memtest-f000.901465.o65:
|
||||||
xa -M -A F000 -O PETSCREEN -c -C -v -o memtest-f000.901465.o memtest-f000.901465.asm
|
xa -M -A F000 -O PETSCREEN -c -C -v -l memtest-f000.901465.map -o memtest-f000.901465.o65 memtest-f000.901465.asm
|
||||||
|
|
||||||
ascii: memtest-f000.901465+ascii.o
|
ascii: memtest-f000.901465+ascii.o65
|
||||||
dd if=memtest-f000.901465+ascii.o bs=1 skip=2 of=memtest-f000.901465+ascii.bin
|
dd if=memtest-f000.901465+ascii.o65 bs=1 skip=2 of=memtest-f000.901465+ascii.bin
|
||||||
|
|
||||||
memtest-f000.901465+ascii.o:
|
memtest-f000.901465+ascii.o65:
|
||||||
xa -M -A F000 -O ASCII -c -C -v -o memtest-f000.901465+ascii.o memtest-f000.901465.asm
|
xa -M '-D_MEMEND=$$1000' -A F000 -O ASCII -c -C -v -l memtest-f000.901465+ascii.map -o memtest-f000.901465+ascii.o65 memtest-f000.901465.asm
|
||||||
|
|
||||||
|
|
||||||
emu5602:
|
emu5602:
|
||||||
gcc -o emu6502 emu6502.c fake6502.c
|
gcc -D_END=$$(cat memtest-f000.901465+ascii.map | grep ^done, | cut -d, -f2 | tr -d ' ,') -o emu6502 emu6502.c fake6502.c
|
||||||
|
|
50
emu6502.c
50
emu6502.c
|
@ -7,23 +7,28 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#define RAMSIZE 0x1000
|
||||||
|
|
||||||
extern uint32_t instructions;
|
extern uint32_t instructions;
|
||||||
extern void reset6502(void);
|
extern void reset6502(void);
|
||||||
extern void step6502(void);
|
extern void step6502(void);
|
||||||
|
|
||||||
uint8_t *ram, *screen, *a000, *b000, *c000, *d000, *e000, *f000;
|
uint8_t *ram, *screen, *f000;
|
||||||
|
|
||||||
|
|
||||||
uint8_t read6502(uint16_t address) {
|
uint8_t read6502(uint16_t address) {
|
||||||
if (address == 0xf27e) {
|
if (address == _END) {
|
||||||
printf("DONE\n");
|
printf("DONE\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
uint8_t value = 0x00;
|
uint8_t value = 0x00;
|
||||||
if (address < 0x4000) {
|
if (address < RAMSIZE) {
|
||||||
|
if (address >= RAMSIZE-16) {
|
||||||
// emulate memory error in uppermost page
|
// emulate memory error in uppermost page
|
||||||
if (address >= 0x3ff0) {
|
|
||||||
value = ram[address] & 0xf7;
|
value = ram[address] & 0xf7;
|
||||||
|
} else if (address >= 0x0100 && address <= 0x01ff) {
|
||||||
|
// simulate broken LSB in stack page
|
||||||
|
value = ram[address & 0xfffe];
|
||||||
} else {
|
} else {
|
||||||
value = ram[address];
|
value = ram[address];
|
||||||
}
|
}
|
||||||
|
@ -32,21 +37,6 @@ uint8_t read6502(uint16_t address) {
|
||||||
// screen buffer is mirrored 4 times, discard upper 2 bytes
|
// screen buffer is mirrored 4 times, discard upper 2 bytes
|
||||||
value = screen[address & 0x03ff];
|
value = screen[address & 0x03ff];
|
||||||
printf("%08x: READ %04x -> %02x\n", instructions, address, value);
|
printf("%08x: READ %04x -> %02x\n", instructions, address, value);
|
||||||
} else if (address >= 0xa000 && address <= 0xafff) {
|
|
||||||
value = a000[address-0xa000];
|
|
||||||
printf("%08x: READ %04x -> %02x\n", instructions, address, value);
|
|
||||||
} else if (address >= 0xb000 && address <= 0xbfff) {
|
|
||||||
value = b000[address-0xb000];
|
|
||||||
printf("%08x: READ %04x -> %02x\n", instructions, address, value);
|
|
||||||
} else if (address >= 0xc000 && address <= 0xcfff) {
|
|
||||||
value = c000[address-0xc000];
|
|
||||||
printf("%08x: READ %04x -> %02x\n", instructions, address, value);
|
|
||||||
} else if (address >= 0xd000 && address <= 0xdfff) {
|
|
||||||
value = d000[address-0xd000];
|
|
||||||
printf("%08x: READ %04x -> %02x\n", instructions, address, value);
|
|
||||||
} else if (address >= 0xe000 && address <= 0xe7ff) {
|
|
||||||
value = e000[address-0xe000];
|
|
||||||
printf("%08x: READ %04x -> %02x\n", instructions, address, value);
|
|
||||||
} else if (address >= 0xf000) {
|
} else if (address >= 0xf000) {
|
||||||
value = f000[address-0xf000];
|
value = f000[address-0xf000];
|
||||||
printf("%08x: READ %04x -> %02x\n", instructions, address, value);
|
printf("%08x: READ %04x -> %02x\n", instructions, address, value);
|
||||||
|
@ -57,10 +47,15 @@ uint8_t read6502(uint16_t address) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void write6502(uint16_t address, uint8_t value) {
|
void write6502(uint16_t address, uint8_t value) {
|
||||||
if (address < 0x4000) {
|
if (address < RAMSIZE) {
|
||||||
printf("%08x: WRITE %04x <- %02x\n", instructions, address, value);
|
printf("%08x: WRITE %04x <- %02x\n", instructions, address, value);
|
||||||
|
// simulate broken LSB in stack page
|
||||||
|
if (address >= 0x100 && address <= 0x1ff) {
|
||||||
|
ram[address & 0xfffe] = value;
|
||||||
|
} else {
|
||||||
ram[address] = value;
|
ram[address] = value;
|
||||||
} else if (address >= 0x800 && address <= 0x8fff) {
|
}
|
||||||
|
} else if (address >= 0x8000 && address <= 0x8fff) {
|
||||||
printf("%08x: WRITE %04x <- %02x, SCREEN(%d,%d)\n", instructions, address, value, (address&0x03ff)%40, (address&0x03ff)/40);
|
printf("%08x: WRITE %04x <- %02x, SCREEN(%d,%d)\n", instructions, address, value, (address&0x03ff)%40, (address&0x03ff)/40);
|
||||||
screen[address & 0x03ff] = value;
|
screen[address & 0x03ff] = value;
|
||||||
} else {
|
} else {
|
||||||
|
@ -69,20 +64,9 @@ void write6502(uint16_t address, uint8_t value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
ram = (uint8_t*) malloc(0x4000);
|
ram = (uint8_t*) malloc(RAMSIZE);
|
||||||
screen = (uint8_t*) malloc(0x400);
|
screen = (uint8_t*) malloc(0x400);
|
||||||
memset(screen, 'X', 0x400);
|
memset(screen, 'X', 0x400);
|
||||||
int afd = open("memtest-9000.901465.bin", O_RDONLY);
|
|
||||||
a000 = mmap(0, 0x1000, PROT_READ, MAP_PRIVATE, afd, 0);
|
|
||||||
int bfd = open("memtest-9000.901465.bin", O_RDONLY);
|
|
||||||
b000 = mmap(0, 0x1000, PROT_READ, MAP_PRIVATE, bfd, 0);
|
|
||||||
int cfd = open("basic-2-c000.901465-01.bin", O_RDONLY);
|
|
||||||
c000 = mmap(0, 0x1000, PROT_READ, MAP_PRIVATE, cfd, 0);
|
|
||||||
int dfd = open("basic-2-d000.901465-02.bin", O_RDONLY);
|
|
||||||
d000 = mmap(0, 0x1000, PROT_READ, MAP_PRIVATE, dfd, 0);
|
|
||||||
int efd = open("edit-2-n.901447-24.bin", O_RDONLY);
|
|
||||||
e000 = mmap(0, 0x0800, PROT_READ, MAP_PRIVATE, efd, 0);
|
|
||||||
//int ffd = open("kernal-2.901465-03.bin", O_RDONLY);
|
|
||||||
int ffd = open("memtest-f000.901465+ascii.bin", O_RDONLY);
|
int ffd = open("memtest-f000.901465+ascii.bin", O_RDONLY);
|
||||||
f000 = mmap(0, 0x1000, PROT_READ, MAP_PRIVATE, ffd, 0);
|
f000 = mmap(0, 0x1000, PROT_READ, MAP_PRIVATE, ffd, 0);
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
|
|
||||||
.word $f000
|
#ifndef _MEMSTART
|
||||||
* = $f000
|
#define _MEMSTART $0007
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _MEMEND
|
||||||
|
#define _MEMEND $4000
|
||||||
|
#endif
|
||||||
|
|
||||||
scrptr = $8000
|
scrptr = $8000
|
||||||
eoscr = $83e7 ; last screen address
|
eoscr = $83e7 ; last screen address
|
||||||
lastline = $83c0 ; start of last line
|
lastline = $83c0 ; start of last line
|
||||||
|
|
||||||
memstart = $0010
|
memstart = _MEMSTART
|
||||||
memend = $4000
|
memend = _MEMEND
|
||||||
|
|
||||||
addr = $0100
|
addr = $0100
|
||||||
aoff = $02
|
aoff = $02
|
||||||
|
@ -15,6 +20,10 @@
|
||||||
pbyte = $04
|
pbyte = $04
|
||||||
scroff = $0605
|
scroff = $0605
|
||||||
|
|
||||||
|
|
||||||
|
.word $f000
|
||||||
|
* = $f000
|
||||||
|
|
||||||
main:
|
main:
|
||||||
sei
|
sei
|
||||||
;; clear screen
|
;; clear screen
|
||||||
|
@ -83,12 +92,24 @@ noskip:
|
||||||
sty eoscr-1
|
sty eoscr-1
|
||||||
;; store pass value at the current address
|
;; store pass value at the current address
|
||||||
lda pbyte
|
lda pbyte
|
||||||
|
;; special case $42: was already written, read only and compare to address' (HI xor LO)
|
||||||
|
cmp #$42
|
||||||
|
beq special42
|
||||||
sta (<addr),Y
|
sta (<addr),Y
|
||||||
;; compare current address to $FF, "continue" if equal
|
;; compare current address to $FF, "continue" if equal
|
||||||
cmp (<addr),Y
|
cmp (<addr),Y
|
||||||
bne print
|
bne print
|
||||||
jmp loopend
|
jmp loopend
|
||||||
|
|
||||||
|
special42:
|
||||||
|
;; compare value in address to (HI xor LO)
|
||||||
|
ldy aoff
|
||||||
|
tya
|
||||||
|
eor >addr
|
||||||
|
cmp (<addr),Y
|
||||||
|
bne print
|
||||||
|
jmp loopend
|
||||||
|
|
||||||
print:
|
print:
|
||||||
;; memory content was not equal, print
|
;; memory content was not equal, print
|
||||||
|
|
||||||
|
@ -371,31 +392,60 @@ passend:
|
||||||
ldy ipass
|
ldy ipass
|
||||||
lda passbytes,Y
|
lda passbytes,Y
|
||||||
cmp #$7F
|
cmp #$7F
|
||||||
beq eot
|
bne passend2
|
||||||
|
jmp done
|
||||||
|
passend2:
|
||||||
iny
|
iny
|
||||||
sty ipass
|
sty ipass
|
||||||
|
lda passbytes,Y
|
||||||
|
cmp #$42
|
||||||
|
beq fill
|
||||||
jmp pass
|
jmp pass
|
||||||
|
|
||||||
|
;; $42 is a special case meant to test proper adressing
|
||||||
|
;; fill value behind each address with (HI xor LO)
|
||||||
|
fill:
|
||||||
|
ldx #>memstart
|
||||||
|
stx >addr
|
||||||
|
ldy #<memstart
|
||||||
|
sty aoff
|
||||||
|
fillloop:
|
||||||
|
tya
|
||||||
|
eor >addr
|
||||||
|
sta (<addr),Y
|
||||||
|
iny
|
||||||
|
sty aoff
|
||||||
|
cpy #00
|
||||||
|
bne fillnocarry
|
||||||
|
inx
|
||||||
|
fillnocarry:
|
||||||
|
stx >addr
|
||||||
|
cpx #>memend
|
||||||
|
bne fillloop
|
||||||
|
jmp pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
hexchars:
|
hexchars:
|
||||||
.asc "0123456789ABCDEF"
|
.asc "0123456789ABCDEF"
|
||||||
passbytes:
|
passbytes:
|
||||||
.byt $FF, $00, $AA, $55, $01, $02, $04, $08, $10, $20, $40, $80, $FE, $FD, $FB, $F7, $EF, $DF, $BF, $7F
|
.byt $FF, $00, $AA, $55, $42, $01, $02, $04, $08, $10, $20, $40, $80, $FE, $FD, $FB, $F7, $EF, $DF, $BF, $7F
|
||||||
passchars:
|
passchars:
|
||||||
.asc "FF00AA550102040810204080FEFDFBF7EFDFBF7F"
|
.asc "FF00AA55XX0102040810204080FEFDFBF7EFDFBF7F"
|
||||||
infotext:
|
infotext:
|
||||||
.asc " = MOS6502 memtest 2022, s3lph ="
|
.asc " CBM 3001 memtest, 2022 s3lph.me"
|
||||||
|
|
||||||
|
done:
|
||||||
|
;; done, loop forever
|
||||||
|
jmp done
|
||||||
|
|
||||||
|
|
||||||
eot:
|
eot:
|
||||||
;; done, loop forever
|
|
||||||
jmp eot
|
|
||||||
|
|
||||||
|
|
||||||
;; Fill with FF
|
;; Fill with FF
|
||||||
* = $fffa
|
* = $fffa
|
||||||
.dsb (*-eot-3), $ff
|
.dsb (*-eot), $ff
|
||||||
;; 6502 vectors
|
;; 6502 vectors
|
||||||
* = $fffa
|
* = $fffa
|
||||||
.byt <main, >main ; NMIV
|
.byt <done, >done ; NMIV
|
||||||
.byt <main, >main ; RESV
|
.byt <main, >main ; RESV
|
||||||
.byt <main, >main ; IRQV
|
.byt <main, >main ; IRQV
|
||||||
|
|
Loading…
Reference in a new issue