mirror of
https://github.com/stid/APPLE-1-ReplicaDue.git
synced 2025-01-14 20:30:30 +00:00
Add ASM + fine tune a bit
This commit is contained in:
parent
8031e9e254
commit
e70361569c
16
ASM/basic_ops.asm
Normal file
16
ASM/basic_ops.asm
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
; TEST ADDRESSING MODES
|
||||
; $FFFC and $FFFD - RESET PROGRAM COUNTER
|
||||
|
||||
processor 6502
|
||||
|
||||
org $FF00
|
||||
|
||||
lda #$00
|
||||
sta $0000
|
||||
loop
|
||||
lda $0000
|
||||
tax
|
||||
inx
|
||||
stx $0000
|
||||
jmp loop
|
15
ASM/read_write.asm
Normal file
15
ASM/read_write.asm
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
; TEST ADDRESSING MODES
|
||||
; $FFFC and $FFFD - RESET PROGRAM COUNTER
|
||||
|
||||
processor 6502
|
||||
|
||||
org $FF00
|
||||
|
||||
loop
|
||||
lda #$AA
|
||||
sta $0000
|
||||
lda #$BB
|
||||
sta $0001
|
||||
nop
|
||||
jmp loop
|
14
ASM/readonly_loop.asm
Normal file
14
ASM/readonly_loop.asm
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
; TEST ADDRESSING MODES
|
||||
; $FFFC and $FFFD - RESET PROGRAM COUNTER
|
||||
|
||||
processor 6502
|
||||
|
||||
org $FF00
|
||||
|
||||
loop
|
||||
nop
|
||||
nop
|
||||
loop2
|
||||
nop
|
||||
jmp loop2
|
259
ASM/woz_monitor.asm
Normal file
259
ASM/woz_monitor.asm
Normal file
@ -0,0 +1,259 @@
|
||||
;-------------------------------------------------------------------------
|
||||
;
|
||||
; The WOZ Monitor for the Apple 1
|
||||
; Written by Steve Wozniak 1976
|
||||
;
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
.CR 6502
|
||||
.OR $FF00
|
||||
.TF WOZMON.HEX,HEX,8
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Memory declaration
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
XAML .EQ $24 Last "opened" location Low
|
||||
XAMH .EQ $25 Last "opened" location High
|
||||
STL .EQ $26 Store address Low
|
||||
STH .EQ $27 Store address High
|
||||
L .EQ $28 Hex value parsing Low
|
||||
H .EQ $29 Hex value parsing High
|
||||
YSAV .EQ $2A Used to see if hex value is given
|
||||
MODE .EQ $2B $00=XAM, $7F=STOR, $AE=BLOCK XAM
|
||||
|
||||
IN .EQ $0200,$027F Input buffer
|
||||
|
||||
KBD .EQ $D010 PIA.A keyboard input
|
||||
KBDCR .EQ $D011 PIA.A keyboard control register
|
||||
DSP .EQ $D012 PIA.B display output register
|
||||
DSPCR .EQ $D013 PIA.B display control register
|
||||
|
||||
; KBD b7..b0 are inputs, b6..b0 is ASCII input, b7 is constant high
|
||||
; Programmed to respond to low to high KBD strobe
|
||||
; DSP b6..b0 are outputs, b7 is input
|
||||
; CB2 goes low when data is written, returns high when CB1 goes high
|
||||
; Interrupts are enabled, though not used. KBD can be jumpered to IRQ,
|
||||
; whereas DSP can be jumpered to NMI.
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Constants
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
BS .EQ $DF Backspace key, arrow left key
|
||||
CR .EQ $8D Carriage Return
|
||||
ESC .EQ $9B ESC key
|
||||
PROMPT .EQ "\" Prompt character
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Let's get started
|
||||
;
|
||||
; Remark the RESET routine is only to be entered by asserting the RESET
|
||||
; line of the system. This ensures that the data direction registers
|
||||
; are selected.
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
RESET CLD Clear decimal arithmetic mode
|
||||
CLI
|
||||
LDY #%0111.1111 Mask for DSP data direction reg
|
||||
STY DSP (DDR mode is assumed after reset)
|
||||
LDA #%1010.0111 KBD and DSP control register mask
|
||||
STA KBDCR Enable interrupts, set CA1, CB1 for
|
||||
STA DSPCR positive edge sense/output mode.
|
||||
|
||||
; Program falls through to the GETLINE routine to save some program bytes
|
||||
; Please note that Y still holds $7F, which will cause an automatic Escape
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; The GETLINE process
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
NOTCR CMP #BS Backspace key?
|
||||
BEQ BACKSPACE Yes
|
||||
CMP #ESC ESC?
|
||||
BEQ ESCAPE Yes
|
||||
INY Advance text index
|
||||
BPL NEXTCHAR Auto ESC if line longer than 127
|
||||
|
||||
ESCAPE LDA #PROMPT Print prompt character
|
||||
JSR ECHO Output it.
|
||||
|
||||
GETLINE LDA #CR Send CR
|
||||
JSR ECHO
|
||||
|
||||
LDY #0+1 Start a new input line
|
||||
BACKSPACE DEY Backup text index
|
||||
BMI GETLINE Oops, line's empty, reinitialize
|
||||
|
||||
NEXTCHAR LDA KBDCR Wait for key press
|
||||
BPL NEXTCHAR No key yet!
|
||||
LDA KBD Load character. B7 should be '1'
|
||||
STA IN,Y Add to text buffer
|
||||
JSR ECHO Display character
|
||||
CMP #CR
|
||||
BNE NOTCR It's not CR!
|
||||
|
||||
; Line received, now let's parse it
|
||||
|
||||
LDY #-1 Reset text index
|
||||
LDA #0 Default mode is XAM
|
||||
TAX X=0
|
||||
|
||||
SETSTOR ASL Leaves $7B if setting STOR mode
|
||||
|
||||
SETMODE STA MODE Set mode flags
|
||||
|
||||
BLSKIP INY Advance text index
|
||||
|
||||
NEXTITEM LDA IN,Y Get character
|
||||
CMP #CR
|
||||
BEQ GETLINE We're done if it's CR!
|
||||
CMP #"."
|
||||
BCC BLSKIP Ignore everything below "."!
|
||||
BEQ SETMODE Set BLOCK XAM mode ("." = $AE)
|
||||
CMP #":"
|
||||
BEQ SETSTOR Set STOR mode! $BA will become $7B
|
||||
CMP #"R"
|
||||
BEQ RUN Run the program! Forget the rest
|
||||
STX L Clear input value (X=0)
|
||||
STX H
|
||||
STY YSAV Save Y for comparison
|
||||
|
||||
; Here we're trying to parse a new hex value
|
||||
|
||||
NEXTHEX LDA IN,Y Get character for hex test
|
||||
EOR #$B0 Map digits to 0-9
|
||||
CMP #9+1 Is it a decimal digit?
|
||||
BCC DIG Yes!
|
||||
ADC #$88 Map letter "A"-"F" to $FA-FF
|
||||
CMP #$FA Hex letter?
|
||||
BCC NOTHEX No! Character not hex
|
||||
|
||||
DIG ASL
|
||||
ASL Hex digit to MSD of A
|
||||
ASL
|
||||
ASL
|
||||
|
||||
LDX #4 Shift count
|
||||
HEXSHIFT ASL Hex digit left, MSB to carry
|
||||
ROL L Rotate into LSD
|
||||
ROL H Rotate into MSD's
|
||||
DEX Done 4 shifts?
|
||||
BNE HEXSHIFT No, loop
|
||||
INY Advance text index
|
||||
BNE NEXTHEX Always taken
|
||||
|
||||
NOTHEX CPY YSAV Was at least 1 hex digit given?
|
||||
BEQ ESCAPE No! Ignore all, start from scratch
|
||||
|
||||
BIT MODE Test MODE byte
|
||||
BVC NOTSTOR B6=0 is STOR, 1 is XAM or BLOCK XAM
|
||||
|
||||
; STOR mode, save LSD of new hex byte
|
||||
|
||||
LDA L LSD's of hex data
|
||||
STA (STL,X) Store current 'store index'(X=0)
|
||||
INC STL Increment store index.
|
||||
BNE NEXTITEM No carry!
|
||||
INC STH Add carry to 'store index' high
|
||||
TONEXTITEM JMP NEXTITEM Get next command item.
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; RUN user's program from last opened location
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
RUN JMP (XAML) Run user's program
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; We're not in Store mode
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
NOTSTOR BMI XAMNEXT B7 = 0 for XAM, 1 for BLOCK XAM
|
||||
|
||||
; We're in XAM mode now
|
||||
|
||||
LDX #2 Copy 2 bytes
|
||||
SETADR LDA L-1,X Copy hex data to
|
||||
STA STL-1,X 'store index'
|
||||
STA XAML-1,X and to 'XAM index'
|
||||
DEX Next of 2 bytes
|
||||
BNE SETADR Loop unless X = 0
|
||||
|
||||
; Print address and data from this address, fall through next BNE.
|
||||
|
||||
NXTPRNT BNE PRDATA NE means no address to print
|
||||
LDA #CR Print CR first
|
||||
JSR ECHO
|
||||
LDA XAMH Output high-order byte of address
|
||||
JSR PRBYTE
|
||||
LDA XAML Output low-order byte of address
|
||||
JSR PRBYTE
|
||||
LDA #":" Print colon
|
||||
JSR ECHO
|
||||
|
||||
PRDATA LDA #" " Print space
|
||||
JSR ECHO
|
||||
LDA (XAML,X) Get data from address (X=0)
|
||||
JSR PRBYTE Output it in hex format
|
||||
XAMNEXT STX MODE 0 -> MODE (XAM mode).
|
||||
LDA XAML See if there's more to print
|
||||
CMP L
|
||||
LDA XAMH
|
||||
SBC H
|
||||
BCS TONEXTITEM Not less! No more data to output
|
||||
|
||||
INC XAML Increment 'examine index'
|
||||
BNE MOD8CHK No carry!
|
||||
INC XAMH
|
||||
|
||||
MOD8CHK LDA XAML If address MOD 8 = 0 start new line
|
||||
AND #%0000.0111
|
||||
BPL NXTPRNT Always taken.
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Subroutine to print a byte in A in hex form (destructive)
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
PRBYTE PHA Save A for LSD
|
||||
LSR
|
||||
LSR
|
||||
LSR MSD to LSD position
|
||||
LSR
|
||||
JSR PRHEX Output hex digit
|
||||
PLA Restore A
|
||||
|
||||
; Fall through to print hex routine
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Subroutine to print a hexadecimal digit
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
PRHEX AND #%0000.1111 Mask LSD for hex print
|
||||
ORA #"0" Add "0"
|
||||
CMP #"9"+1 Is it a decimal digit?
|
||||
BCC ECHO Yes! output it
|
||||
ADC #6 Add offset for letter A-F
|
||||
|
||||
; Fall through to print routine
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Subroutine to print a character to the terminal
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
ECHO BIT DSP DA bit (B7) cleared yet?
|
||||
BMI ECHO No! Wait for display ready
|
||||
STA DSP Output character. Sets DA
|
||||
RTS
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Vector area
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
.DA $0000 Unused, what a pity
|
||||
NMI_VEC .DA $0F00 NMI vector
|
||||
RESET_VEC .DA RESET RESET vector
|
||||
IRQ_VEC .DA $0000 IRQ vector
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
.LI OFF
|
258
ASM/woz_monitor_dasm.asm
Normal file
258
ASM/woz_monitor_dasm.asm
Normal file
@ -0,0 +1,258 @@
|
||||
;-------------------------------------------------------------------------
|
||||
;
|
||||
; The WOZ Monitor for the Apple 1
|
||||
; Written by Steve Wozniak 1976
|
||||
;
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
processor 6502
|
||||
org $FF00
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Memory declaration
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
XAML .EQ $24 Last "opened" location Low
|
||||
XAMH .EQ $25 Last "opened" location High
|
||||
STL .EQ $26 Store address Low
|
||||
STH .EQ $27 Store address High
|
||||
L .EQ $28 Hex value parsing Low
|
||||
H .EQ $29 Hex value parsing High
|
||||
YSAV .EQ $2A Used to see if hex value is given
|
||||
MODE .EQ $2B $00=XAM, $7F=STOR, $AE=BLOCK XAM
|
||||
|
||||
IN .EQ $0200,$027F Input buffer
|
||||
|
||||
KBD .EQ $D010 PIA.A keyboard input
|
||||
KBDCR .EQ $D011 PIA.A keyboard control register
|
||||
DSP .EQ $D012 PIA.B display output register
|
||||
DSPCR .EQ $D013 PIA.B display control register
|
||||
|
||||
; KBD b7..b0 are inputs, b6..b0 is ASCII input, b7 is constant high
|
||||
; Programmed to respond to low to high KBD strobe
|
||||
; DSP b6..b0 are outputs, b7 is input
|
||||
; CB2 goes low when data is written, returns high when CB1 goes high
|
||||
; Interrupts are enabled, though not used. KBD can be jumpered to IRQ,
|
||||
; whereas DSP can be jumpered to NMI.
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Constants
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
BS .EQ $DF Backspace key, arrow left key
|
||||
CR .EQ $8D Carriage Return
|
||||
ESC .EQ $9B ESC key
|
||||
PROMPT .EQ "\" Prompt character
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Let's get started
|
||||
;
|
||||
; Remark the RESET routine is only to be entered by asserting the RESET
|
||||
; line of the system. This ensures that the data direction registers
|
||||
; are selected.
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
RESET CLD Clear decimal arithmetic mode
|
||||
CLI
|
||||
LDY #%0111.1111 Mask for DSP data direction reg
|
||||
STY DSP (DDR mode is assumed after reset)
|
||||
LDA #%1010.0111 KBD and DSP control register mask
|
||||
STA KBDCR Enable interrupts, set CA1, CB1 for
|
||||
STA DSPCR positive edge sense/output mode.
|
||||
|
||||
; Program falls through to the GETLINE routine to save some program bytes
|
||||
; Please note that Y still holds $7F, which will cause an automatic Escape
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; The GETLINE process
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
NOTCR CMP #BS Backspace key?
|
||||
BEQ BACKSPACE Yes
|
||||
CMP #ESC ESC?
|
||||
BEQ ESCAPE Yes
|
||||
INY Advance text index
|
||||
BPL NEXTCHAR Auto ESC if line longer than 127
|
||||
|
||||
ESCAPE LDA #PROMPT Print prompt character
|
||||
JSR ECHO Output it.
|
||||
|
||||
GETLINE LDA #CR Send CR
|
||||
JSR ECHO
|
||||
|
||||
LDY #0+1 Start a new input line
|
||||
BACKSPACE DEY Backup text index
|
||||
BMI GETLINE Oops, line's empty, reinitialize
|
||||
|
||||
NEXTCHAR LDA KBDCR Wait for key press
|
||||
BPL NEXTCHAR No key yet!
|
||||
LDA KBD Load character. B7 should be '1'
|
||||
STA IN,Y Add to text buffer
|
||||
JSR ECHO Display character
|
||||
CMP #CR
|
||||
BNE NOTCR It's not CR!
|
||||
|
||||
; Line received, now let's parse it
|
||||
|
||||
LDY #-1 Reset text index
|
||||
LDA #0 Default mode is XAM
|
||||
TAX X=0
|
||||
|
||||
SETSTOR ASL Leaves $7B if setting STOR mode
|
||||
|
||||
SETMODE STA MODE Set mode flags
|
||||
|
||||
BLSKIP INY Advance text index
|
||||
|
||||
NEXTITEM LDA IN,Y Get character
|
||||
CMP #CR
|
||||
BEQ GETLINE We're done if it's CR!
|
||||
CMP #"."
|
||||
BCC BLSKIP Ignore everything below "."!
|
||||
BEQ SETMODE Set BLOCK XAM mode ("." = $AE)
|
||||
CMP #":"
|
||||
BEQ SETSTOR Set STOR mode! $BA will become $7B
|
||||
CMP #"R"
|
||||
BEQ RUN Run the program! Forget the rest
|
||||
STX L Clear input value (X=0)
|
||||
STX H
|
||||
STY YSAV Save Y for comparison
|
||||
|
||||
; Here we're trying to parse a new hex value
|
||||
|
||||
NEXTHEX LDA IN,Y Get character for hex test
|
||||
EOR #$B0 Map digits to 0-9
|
||||
CMP #9+1 Is it a decimal digit?
|
||||
BCC DIG Yes!
|
||||
ADC #$88 Map letter "A"-"F" to $FA-FF
|
||||
CMP #$FA Hex letter?
|
||||
BCC NOTHEX No! Character not hex
|
||||
|
||||
DIG ASL
|
||||
ASL Hex digit to MSD of A
|
||||
ASL
|
||||
ASL
|
||||
|
||||
LDX #4 Shift count
|
||||
HEXSHIFT ASL Hex digit left, MSB to carry
|
||||
ROL L Rotate into LSD
|
||||
ROL H Rotate into MSD's
|
||||
DEX Done 4 shifts?
|
||||
BNE HEXSHIFT No, loop
|
||||
INY Advance text index
|
||||
BNE NEXTHEX Always taken
|
||||
|
||||
NOTHEX CPY YSAV Was at least 1 hex digit given?
|
||||
BEQ ESCAPE No! Ignore all, start from scratch
|
||||
|
||||
BIT MODE Test MODE byte
|
||||
BVC NOTSTOR B6=0 is STOR, 1 is XAM or BLOCK XAM
|
||||
|
||||
; STOR mode, save LSD of new hex byte
|
||||
|
||||
LDA L LSD's of hex data
|
||||
STA (STL,X) Store current 'store index'(X=0)
|
||||
INC STL Increment store index.
|
||||
BNE NEXTITEM No carry!
|
||||
INC STH Add carry to 'store index' high
|
||||
TONEXTITEM JMP NEXTITEM Get next command item.
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; RUN user's program from last opened location
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
RUN JMP (XAML) Run user's program
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; We're not in Store mode
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
NOTSTOR BMI XAMNEXT B7 = 0 for XAM, 1 for BLOCK XAM
|
||||
|
||||
; We're in XAM mode now
|
||||
|
||||
LDX #2 Copy 2 bytes
|
||||
SETADR LDA L-1,X Copy hex data to
|
||||
STA STL-1,X 'store index'
|
||||
STA XAML-1,X and to 'XAM index'
|
||||
DEX Next of 2 bytes
|
||||
BNE SETADR Loop unless X = 0
|
||||
|
||||
; Print address and data from this address, fall through next BNE.
|
||||
|
||||
NXTPRNT BNE PRDATA NE means no address to print
|
||||
LDA #CR Print CR first
|
||||
JSR ECHO
|
||||
LDA XAMH Output high-order byte of address
|
||||
JSR PRBYTE
|
||||
LDA XAML Output low-order byte of address
|
||||
JSR PRBYTE
|
||||
LDA #":" Print colon
|
||||
JSR ECHO
|
||||
|
||||
PRDATA LDA #" " Print space
|
||||
JSR ECHO
|
||||
LDA (XAML,X) Get data from address (X=0)
|
||||
JSR PRBYTE Output it in hex format
|
||||
XAMNEXT STX MODE 0 -> MODE (XAM mode).
|
||||
LDA XAML See if there's more to print
|
||||
CMP L
|
||||
LDA XAMH
|
||||
SBC H
|
||||
BCS TONEXTITEM Not less! No more data to output
|
||||
|
||||
INC XAML Increment 'examine index'
|
||||
BNE MOD8CHK No carry!
|
||||
INC XAMH
|
||||
|
||||
MOD8CHK LDA XAML If address MOD 8 = 0 start new line
|
||||
AND #%0000.0111
|
||||
BPL NXTPRNT Always taken.
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Subroutine to print a byte in A in hex form (destructive)
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
PRBYTE PHA Save A for LSD
|
||||
LSR
|
||||
LSR
|
||||
LSR MSD to LSD position
|
||||
LSR
|
||||
JSR PRHEX Output hex digit
|
||||
PLA Restore A
|
||||
|
||||
; Fall through to print hex routine
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Subroutine to print a hexadecimal digit
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
PRHEX AND #%0000.1111 Mask LSD for hex print
|
||||
ORA #"0" Add "0"
|
||||
CMP #"9"+1 Is it a decimal digit?
|
||||
BCC ECHO Yes! output it
|
||||
ADC #6 Add offset for letter A-F
|
||||
|
||||
; Fall through to print routine
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Subroutine to print a character to the terminal
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
ECHO BIT DSP DA bit (B7) cleared yet?
|
||||
BMI ECHO No! Wait for display ready
|
||||
STA DSP Output character. Sets DA
|
||||
RTS
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Vector area
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
.DA $0000 Unused, what a pity
|
||||
NMI_VEC .DA $0F00 NMI vector
|
||||
RESET_VEC .DA RESET RESET vector
|
||||
IRQ_VEC .DA $0000 IRQ vector
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
.LI OFF
|
100
src/main.cpp
100
src/main.cpp
@ -3,50 +3,60 @@
|
||||
|
||||
#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
|
||||
|
||||
const int CLOCK_PIN = 52;
|
||||
const int RW_PIN = 53;
|
||||
const int CLOCK_DELAY = 100;
|
||||
const int SERIAL_SPEED = 115200; // Arduino Serial Speed
|
||||
|
||||
const int CLOCK_PIN = 52; // TO 6502 CLOCK
|
||||
const int RW_PIN = 53; // TO 6502 R/W
|
||||
const int CLOCK_DELAY = 1; // HIGH / LOW CLOCK STATE DELAY
|
||||
|
||||
const int NUM_ADDR_PINS = 16;
|
||||
const int NUM_DATA_PINS = 8;
|
||||
const int ADDRESS_PINS[] = {44,45,2,3,4,5,6,7,8,9,10,11,12,13,46,47};
|
||||
const int DATA_PINS[] = {30,31,32,33,34,35,36,37};
|
||||
const int ADDRESS_PINS[] = {44,45,2,3,4,5,6,7,8,9,10,11,12,13,46,47}; // TO ADDRESS PIN 1-15 6502
|
||||
const int DATA_PINS[] = {30,31,32,33,34,35,36,37}; // TO DATA BUS PIN 0-7 6502
|
||||
|
||||
const unsigned int ROM_ADDR = 0xFF00;
|
||||
const unsigned int RAM_BANK1_ADDR = 0x0000;
|
||||
const unsigned int RAM_BANK2_ADDR = 0xE000;
|
||||
const unsigned int PIA_ADDR = 0xD000;
|
||||
const unsigned int ROM_ADDR = 0xFF00; // ROM
|
||||
const unsigned int RAM_BANK1_ADDR = 0x0000; // RAM
|
||||
const unsigned int RAM_BANK2_ADDR = 0xE000; // EXTENDED RAM
|
||||
|
||||
const unsigned int XAML = 0x24;
|
||||
const unsigned int XAMH = 0x25;
|
||||
const unsigned int STL = 0x26;
|
||||
const unsigned int STH = 0x27;
|
||||
const unsigned int L = 0x28;
|
||||
const unsigned int H = 0x29;
|
||||
const unsigned int YSAV = 0x2A;
|
||||
const unsigned int MODE = 0x2B;
|
||||
|
||||
const unsigned int IN = 0x200;
|
||||
const unsigned int XAML = 0x24; // Last "opened" location Low
|
||||
const unsigned int XAMH = 0x25; // Last "opened" location High
|
||||
const unsigned int STL = 0x26; // Store address Low
|
||||
const unsigned int STH = 0x27; // Store address High
|
||||
const unsigned int L = 0x28; // Hex value parsing Low
|
||||
const unsigned int H = 0x29; // Hex value parsing High
|
||||
const unsigned int YSAV = 0x2A; // Used to see if hex value is given
|
||||
const unsigned int MODE = 0x2B; // $00=XAM, $7F=STOR, $AE=BLOCK XAM
|
||||
const unsigned int IN = 0x200; // Input buffer ($0200,$027F)
|
||||
|
||||
const int RAM_BANK_1_SIZE = 4096;
|
||||
const int RAM_BANK_2_SIZE = 4096;
|
||||
unsigned char RAM_BANK_1[RAM_BANK_1_SIZE];
|
||||
|
||||
unsigned int address;
|
||||
unsigned char bus_data=0;
|
||||
int rw_state = HIGH;
|
||||
|
||||
const unsigned int KBD_ADDR = 0xD010;
|
||||
const unsigned int KBDCR_ADDR = 0xD011;
|
||||
const unsigned int DSP_ADDR = 0xD012;
|
||||
const unsigned int DSPCR_ADDR = 0xD013;
|
||||
|
||||
|
||||
// PIA MAPPING 6821
|
||||
const unsigned int PIA_ADDR = 0xD000; // PIA 6821 ADDR BASE SPACE
|
||||
const unsigned int KBD_ADDR = 0xD010; // Keyb Char - B7 High on keypress
|
||||
const unsigned int KBDCR_ADDR = 0xD011; // Keyb Status - B7 High on keypress / Low when ready
|
||||
const unsigned int DSP_ADDR = 0xD012; // DSP Char
|
||||
const unsigned int DSPCR_ADDR = 0xD013; // DSP Status - B7 Low if VIDEO ready
|
||||
unsigned char KBD = 0;
|
||||
unsigned char KBDCR = 0;
|
||||
unsigned char DSP = 0;
|
||||
unsigned char DSPCR = 0;
|
||||
|
||||
const unsigned char BS = 0xDF; // Backspace key, arrow left key (B7 High)
|
||||
const unsigned char CR = 0x8D; // Carriage Return (B7 High)
|
||||
const unsigned char ESC = 0x9B; // ESC key (B7 High)
|
||||
|
||||
unsigned int address; // Current address (from 6502)
|
||||
unsigned char bus_data; // Data Bus value (from 6502)
|
||||
int rw_state; // Current R/W state (from 6502)
|
||||
|
||||
|
||||
unsigned int pre_address; // Current address (from 6502)
|
||||
unsigned char pre_bus_data; // Data Bus value (from 6502)
|
||||
int pre_rw_state; // Current R/W state (from 6502)
|
||||
|
||||
|
||||
void setupAddressPins() {
|
||||
for (int i = 0; i < NUM_ADDR_PINS; ++i) {
|
||||
pinMode(ADDRESS_PINS[i], INPUT);
|
||||
@ -82,19 +92,23 @@ void handleRWState() {
|
||||
if (rw_state != curent_rw_state) {
|
||||
rw_state=curent_rw_state;
|
||||
if (rw_state) {
|
||||
// State HIGH - WRITE TO 6502 Data Bus
|
||||
busMode(OUTPUT);
|
||||
} else {
|
||||
// State LOW - READ FROM 6502 Data Bus
|
||||
busMode(INPUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send a byte to the 6502 DATA BUS
|
||||
void byteToDataBus(unsigned char data) {
|
||||
for (int i = 0; i < NUM_DATA_PINS; i++) {
|
||||
digitalWrite(DATA_PINS[i], CHECK_BIT(data, i));
|
||||
}
|
||||
}
|
||||
|
||||
// READ FROM DATA BUS - STORE AT RELATED ADDRESS
|
||||
void readFromDataBus() {
|
||||
readData();
|
||||
|
||||
@ -117,12 +131,14 @@ void readFromDataBus() {
|
||||
break;
|
||||
case DSP_ADDR:
|
||||
DSP = bus_data;
|
||||
if (DSP == 0x8D) {
|
||||
if (DSP == CR) {
|
||||
// Simulate CR
|
||||
Serial.write('\r');
|
||||
Serial.write('\n');
|
||||
} else {
|
||||
Serial.write(DSP & 0x7F);
|
||||
}
|
||||
// Display Ready - clear B7
|
||||
bitClear(DSP, 7);
|
||||
break;
|
||||
case DSPCR_ADDR:
|
||||
@ -133,6 +149,7 @@ void readFromDataBus() {
|
||||
}
|
||||
}
|
||||
|
||||
// WRITE FROM DATA BUS A BYTE FROM RELATED ADDRESS
|
||||
void writeToDataBus() {
|
||||
unsigned char val=0;
|
||||
|
||||
@ -147,10 +164,11 @@ void writeToDataBus() {
|
||||
val=ROM[address-ROM_ADDR];
|
||||
break;
|
||||
case 0xD:
|
||||
// 6821
|
||||
// PIA 6821
|
||||
switch (address) {
|
||||
case KBD_ADDR:
|
||||
val=KBD;
|
||||
// We'v read the char, clear B7
|
||||
bitClear(KBDCR, 7);
|
||||
break;
|
||||
case KBDCR_ADDR:
|
||||
@ -178,19 +196,24 @@ void handleKeyboard() {
|
||||
// KEYBOARD INPUT
|
||||
if (Serial.available() > 0) {
|
||||
char tempKBD = Serial.read();
|
||||
|
||||
switch (tempKBD) {
|
||||
case 0xA:
|
||||
// Not expected from KEYB
|
||||
// Just ignore
|
||||
return;
|
||||
break;
|
||||
case 0xD:
|
||||
// CR
|
||||
tempKBD = 0x0D;
|
||||
break;
|
||||
}
|
||||
|
||||
KBD = tempKBD;
|
||||
|
||||
// Step B7 on KBD so that the code know a new char is in
|
||||
bitSet(KBD, 7);
|
||||
bitSet(KBDCR, 7);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -199,7 +222,7 @@ void setup() {
|
||||
pinMode(RW_PIN, INPUT);
|
||||
setupAddressPins();
|
||||
busMode(OUTPUT);
|
||||
Serial.begin (115200);
|
||||
Serial.begin(SERIAL_SPEED);
|
||||
|
||||
Serial.println("----------------------------");
|
||||
Serial.println("APPLE 1 REPLICA by =STID=");
|
||||
@ -218,7 +241,6 @@ void setup() {
|
||||
}
|
||||
|
||||
void loop () {
|
||||
|
||||
// LOW CLOCK
|
||||
digitalWrite(CLOCK_PIN, LOW);
|
||||
delayMicroseconds(CLOCK_DELAY);
|
||||
@ -234,16 +256,18 @@ void loop () {
|
||||
readAddress();
|
||||
|
||||
// READ OR WRITE TO BUS?
|
||||
if (rw_state) {
|
||||
writeToDataBus();
|
||||
|
||||
if (pre_address != address || pre_rw_state != rw_state) {
|
||||
rw_state ? writeToDataBus() : readFromDataBus();
|
||||
} else {
|
||||
readFromDataBus();
|
||||
pre_address = address;
|
||||
pre_rw_state = rw_state;
|
||||
}
|
||||
|
||||
handleKeyboard();
|
||||
}
|
||||
|
||||
// WOZ TEST
|
||||
// WOZ TEST (As on the Apple 1 Manual)
|
||||
// 0:A9 9 AA 20 EF FF E8 8A 4C 2 0
|
||||
|
||||
// HELLO WORLD
|
||||
|
Loading…
x
Reference in New Issue
Block a user