@cbscpe : You don't clear interrupt flag at the beginning of the code. IRQs will be inhibited that way.
Here is my take to the stuff. I didn't want to introduce another input to the GAL as I would be using S.O. anyway for a little bit of speed.
Here is my code, S.O. signals end of each byte, IRQ and NMI stores 1 and 0 into accumulator respectively. I also manually modified PLD source for WinCUPL to optimize it. The issue is, I didn't get the expected result out of it. I don't have 65c02 so single stepping is a big no. I used the trick previously I used to test rom & ram access. I only have 32k ram, ROM decodes to $E000-$FFFF, Ram decodes to $0000-$7FFF. I have a 3 to 8 decoder so I use additional decoding signals to interrupt arduino. $8000-$9FFF -> Int 0, $A000-$BFFF -> Int 1. I do access these locations to transmit information to arduino. This previously worked well and what I used to test my apartment style boards for errors.
Can you spot any apparent error in below setup?
Contents of boot loader (6502Bootloaderx.65s)
Code:
BOOTLOADER = $00
*=$FFE0
.BYTE 0, 0, 0, 0, 0, 0, 0, 0 ; Will be replaced by Do not care bytes.
RESETROUTINE
LDX #$00 ; Init byte storing index
CLI ; Enable Interrupts
SEC ; Set Carry for IRQ (IRQ pulls from stack)
NEXT
CLV
BVC *
STA BOOTLOADER,X
INX
BNE NEXT
JMP BOOTLOADER
NMIROUTINE
ASL
RTI
IRQROUTINE
ROL
RTI
*=$FFFA
.WORD NMIROUTINE
.WORD RESETROUTINE
.WORD IRQROUTINE
PLD code (Data pins reversed as I created a board out of this and aligned Data pins to 6502 data bus locations)
Code:
Name bootloader ;
PartNo 00 ;
Date 27.07.2015 ;
Revision 01 ;
Designer i_r_on ;
Company none;
Assembly None ;
Location ;
Device g16v8;
/* *************** INPUT PINS *********************/
PIN 2 = A0 ; /* */
PIN 3 = A1 ; /* */
PIN 4 = A2 ; /* */
PIN 5 = A3 ; /* */
PIN 6 = A4 ; /* */
PIN 11 = !OE ; /* */
/* *************** OUTPUT PINS *********************/
PIN 12 = D7 ; /* */
PIN 13 = D6 ; /* */
PIN 14 = D5 ; /* */
PIN 15 = D4 ; /* */
PIN 16 = D3 ; /* */
PIN 17 = D2 ; /* */
PIN 18 = D1 ; /* */
PIN 19 = D0 ; /* */
FIELD ADDR = [A4..0];
FIELD DATA = [D7..0];
[D7..0].oe = OE;
TABLE ADDR => DATA {
[00] => 'h'xx;
[01] => 'h'xx;
[02] => 'h'xx;
[03] => 'h'xx;
[04] => 'h'xx;
[05] => 'h'xx;
[06] => 'h'xx;
[07] => 'h'xx;
[08] => 'h'a2;
[09] => 'h'00;
[0a] => 'h'58;
[0b] => 'h'38;
[0c] => 'h'b8;
[0d] => 'h'50;
[0e] => 'h'fe;
[0f] => 'h'95;
[10] => 'h'00;
[11] => 'h'e8;
[12] => 'h'd0;
[13] => 'h'f8;
[14] => 'h'4c;
[15] => 'h'0x;
[16] => 'h'00;
[17] => 'h'0a;
[18] => 'h'40;
[19] => 'h'2a;
[1a] => 'b'xxx10111;
[1b] => 'b'11xxxxxx;
[1c] => 'h'xxx01000;
[1d] => 'b'11xxxxxx;
[1e] => 'h'xxx11001;
[1f] => 'b'11xxxxxx;
}
Second stage loader of the test routine (2ndBootloader.65s)
Code:
PAYLOADADDRESS = $7000
*=$0000
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
SEI
CLV
CLD
LDX #$FF
TXS
CLI
INX
NEXT
LDA PAYLOAD,X
STA PAYLOADADDRESS,X
INX
BNE NEXT
JMP PAYLOADADDRESS
*=$002F
.BYTE 0
PAYLOAD
;Actual Payload will be appended here...
;Above code copies payload to PAYLOADADDRESS and controls
;transfer there.
Actual test routine (MainPayload.65s)
Code:
*=$7000
;TEST STACK ACCESS
LDA #$99
PHA
LDA #$00
PLA
CMP #$99
BNE FAIL
JSR SENDBYTE ; Send $99 as a success status for stack test
JMP ZEROPAGETEST
FAIL
LDA #$CC
JSR SENDBYTE
ZEROPAGETEST
LDX #00
; Write $77 through $00 to $FF
LDA #$77
NEXTLOC
STA $00, X
INX
BNE NEXTLOC
; Try to read $77 through $00 to $FF
LDA #$00
LDX #$00
NEXTLOCREAD
LDA $00, X
CMP #$77
BNE FAILZEROPAGE
INX
BNE NEXTLOCREAD
; Zero page test success
LDA #$99
JSR SENDBYTE
JMP MEMTEST
; Zero page test fail
FAILZEROPAGE
LDA #$CC
JSR SENDBYTE
MEMTEST
LDY #$00
LDA #$00
STA $FB
LDA #$7F
STA $FC
NEXTPAGE
LDA #$01
INCURPAGE
STA ($FB), Y
CLC
ADC #$01
INY
BNE INCURPAGE
DEC $FC
BNE NEXTPAGE
; Read to test
LDY #$00
LDA #$00
STA $FB
LDA #$7F
STA $FC
NEXTPAGEREAD
LDA #$01
INCURPAGEREAD
CMP ($FB), Y
BNE MEMTESTFAIL
CLC
ADC #$01
INY
BNE INCURPAGEREAD
DEC $FC
BNE NEXTPAGEREAD
LDA #$99
JSR SENDBYTE
JMP ENDLESS
MEMTESTFAIL
LDA #$CC
JSR SENDBYTE
CLV
ENDLESS
BVC ENDLESS
SENDBYTE
NEXT
LDY #$08
SINGLEBITSEND
LDX #$40
CONSUMETIME
DEX
BNE CONSUMETIME
ROL
BCS ONE
STA $8000
JMP NEXTBIT
ONE
STA $A000
NEXTBIT
DEY
BNE SINGLEBITSEND
RTS
So I compile all of this to create under 256 bytes code like this,
Code:
64tass -c -b 6502BootLoader3.65s -o 6502BootLoader3.65s.bin
64tass -c -b 2ndbootloader.65s -o 2ndbootloader.65s.bin
64tass -c -b MainPayload.65s -o MainPayload.65s.bin
copy 2ndBootloader.65s.bin + MainPayload.65s.bin Bootloader.bin /b
bin2h -cz bootloader <Bootloader.bin > Bootloader.h
And here is relevant part of my arduino code,
Code:
void TransmitByteSpecial(unsigned char val) {
unsigned char mask = 0x80;
for (int i = 0; i<8; i++) {
if (val & mask) {
//Transmit 1
digitalWrite(IRQ, LOW);
delayMicroseconds(5); //Wait 5 micro seconds for interrupt to trigger (approx. 5 cycles)
digitalWrite(IRQ, HIGH);
delayMicroseconds(40); //Wait 40 micro seconds for interrupt to finish it's job (approx. 40 cycles)
} else {
//Transmit 0
digitalWrite(NMI, LOW);
delayMicroseconds(5); //Wait 5 micro seconds for interrupt to trigger (approx. 5 cycles)
digitalWrite(NMI, HIGH);
delayMicroseconds(40); //Wait 40 micro seconds for interrupt to finish it's job (approx. 40 cycles)
}
mask = mask>>1;
}
// [Interrupt enclosure end(wait before byte storage)]
digitalWrite(SO, LOW);
delayMicroseconds(5); //Wait LOOP BVC LOOP on 6502 side
digitalWrite(SO, HIGH);
delayMicroseconds(100);
}
void LoaderTest2() {
delay(1000);
attachInterrupt(0, serialInputZero ,FALLING);
attachInterrupt(1, serialInputOne ,FALLING);
delay(1000);
Reset6502();
delay(250);
for (int i = 0;i<256;i++) {
if (i<bootloader_size) {
TransmitByteSpecial(bootloader[i]);
} else {
TransmitByteSpecial(0);
}
}
delay(5000);
Serial.println();
Serial.println(F("Test is dones, detaching interrupts!"));
detachInterrupt(0);
detachInterrupt(1);
}