mirror of
https://github.com/stid/APPLE-1-ReplicaDue.git
synced 2025-01-28 04:32:32 +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)))
|
#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
|
||||||
|
|
||||||
const int CLOCK_PIN = 52;
|
const int SERIAL_SPEED = 115200; // Arduino Serial Speed
|
||||||
const int RW_PIN = 53;
|
|
||||||
const int CLOCK_DELAY = 100;
|
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_ADDR_PINS = 16;
|
||||||
const int NUM_DATA_PINS = 8;
|
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 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};
|
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 ROM_ADDR = 0xFF00; // ROM
|
||||||
const unsigned int RAM_BANK1_ADDR = 0x0000;
|
const unsigned int RAM_BANK1_ADDR = 0x0000; // RAM
|
||||||
const unsigned int RAM_BANK2_ADDR = 0xE000;
|
const unsigned int RAM_BANK2_ADDR = 0xE000; // EXTENDED RAM
|
||||||
const unsigned int PIA_ADDR = 0xD000;
|
|
||||||
|
|
||||||
const unsigned int XAML = 0x24;
|
const unsigned int XAML = 0x24; // Last "opened" location Low
|
||||||
const unsigned int XAMH = 0x25;
|
const unsigned int XAMH = 0x25; // Last "opened" location High
|
||||||
const unsigned int STL = 0x26;
|
const unsigned int STL = 0x26; // Store address Low
|
||||||
const unsigned int STH = 0x27;
|
const unsigned int STH = 0x27; // Store address High
|
||||||
const unsigned int L = 0x28;
|
const unsigned int L = 0x28; // Hex value parsing Low
|
||||||
const unsigned int H = 0x29;
|
const unsigned int H = 0x29; // Hex value parsing High
|
||||||
const unsigned int YSAV = 0x2A;
|
const unsigned int YSAV = 0x2A; // Used to see if hex value is given
|
||||||
const unsigned int MODE = 0x2B;
|
const unsigned int MODE = 0x2B; // $00=XAM, $7F=STOR, $AE=BLOCK XAM
|
||||||
|
const unsigned int IN = 0x200; // Input buffer ($0200,$027F)
|
||||||
const unsigned int IN = 0x200;
|
|
||||||
|
|
||||||
const int RAM_BANK_1_SIZE = 4096;
|
const int RAM_BANK_1_SIZE = 4096;
|
||||||
const int RAM_BANK_2_SIZE = 4096;
|
const int RAM_BANK_2_SIZE = 4096;
|
||||||
unsigned char RAM_BANK_1[RAM_BANK_1_SIZE];
|
unsigned char RAM_BANK_1[RAM_BANK_1_SIZE];
|
||||||
|
|
||||||
unsigned int address;
|
// PIA MAPPING 6821
|
||||||
unsigned char bus_data=0;
|
const unsigned int PIA_ADDR = 0xD000; // PIA 6821 ADDR BASE SPACE
|
||||||
int rw_state = HIGH;
|
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 KBD_ADDR = 0xD010;
|
const unsigned int DSP_ADDR = 0xD012; // DSP Char
|
||||||
const unsigned int KBDCR_ADDR = 0xD011;
|
const unsigned int DSPCR_ADDR = 0xD013; // DSP Status - B7 Low if VIDEO ready
|
||||||
const unsigned int DSP_ADDR = 0xD012;
|
|
||||||
const unsigned int DSPCR_ADDR = 0xD013;
|
|
||||||
|
|
||||||
|
|
||||||
unsigned char KBD = 0;
|
unsigned char KBD = 0;
|
||||||
unsigned char KBDCR = 0;
|
unsigned char KBDCR = 0;
|
||||||
unsigned char DSP = 0;
|
unsigned char DSP = 0;
|
||||||
unsigned char DSPCR = 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() {
|
void setupAddressPins() {
|
||||||
for (int i = 0; i < NUM_ADDR_PINS; ++i) {
|
for (int i = 0; i < NUM_ADDR_PINS; ++i) {
|
||||||
pinMode(ADDRESS_PINS[i], INPUT);
|
pinMode(ADDRESS_PINS[i], INPUT);
|
||||||
@ -82,19 +92,23 @@ void handleRWState() {
|
|||||||
if (rw_state != curent_rw_state) {
|
if (rw_state != curent_rw_state) {
|
||||||
rw_state=curent_rw_state;
|
rw_state=curent_rw_state;
|
||||||
if (rw_state) {
|
if (rw_state) {
|
||||||
|
// State HIGH - WRITE TO 6502 Data Bus
|
||||||
busMode(OUTPUT);
|
busMode(OUTPUT);
|
||||||
} else {
|
} else {
|
||||||
|
// State LOW - READ FROM 6502 Data Bus
|
||||||
busMode(INPUT);
|
busMode(INPUT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Send a byte to the 6502 DATA BUS
|
||||||
void byteToDataBus(unsigned char data) {
|
void byteToDataBus(unsigned char data) {
|
||||||
for (int i = 0; i < NUM_DATA_PINS; i++) {
|
for (int i = 0; i < NUM_DATA_PINS; i++) {
|
||||||
digitalWrite(DATA_PINS[i], CHECK_BIT(data, i));
|
digitalWrite(DATA_PINS[i], CHECK_BIT(data, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// READ FROM DATA BUS - STORE AT RELATED ADDRESS
|
||||||
void readFromDataBus() {
|
void readFromDataBus() {
|
||||||
readData();
|
readData();
|
||||||
|
|
||||||
@ -117,12 +131,14 @@ void readFromDataBus() {
|
|||||||
break;
|
break;
|
||||||
case DSP_ADDR:
|
case DSP_ADDR:
|
||||||
DSP = bus_data;
|
DSP = bus_data;
|
||||||
if (DSP == 0x8D) {
|
if (DSP == CR) {
|
||||||
|
// Simulate CR
|
||||||
Serial.write('\r');
|
Serial.write('\r');
|
||||||
Serial.write('\n');
|
Serial.write('\n');
|
||||||
} else {
|
} else {
|
||||||
Serial.write(DSP & 0x7F);
|
Serial.write(DSP & 0x7F);
|
||||||
}
|
}
|
||||||
|
// Display Ready - clear B7
|
||||||
bitClear(DSP, 7);
|
bitClear(DSP, 7);
|
||||||
break;
|
break;
|
||||||
case DSPCR_ADDR:
|
case DSPCR_ADDR:
|
||||||
@ -133,6 +149,7 @@ void readFromDataBus() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WRITE FROM DATA BUS A BYTE FROM RELATED ADDRESS
|
||||||
void writeToDataBus() {
|
void writeToDataBus() {
|
||||||
unsigned char val=0;
|
unsigned char val=0;
|
||||||
|
|
||||||
@ -147,10 +164,11 @@ void writeToDataBus() {
|
|||||||
val=ROM[address-ROM_ADDR];
|
val=ROM[address-ROM_ADDR];
|
||||||
break;
|
break;
|
||||||
case 0xD:
|
case 0xD:
|
||||||
// 6821
|
// PIA 6821
|
||||||
switch (address) {
|
switch (address) {
|
||||||
case KBD_ADDR:
|
case KBD_ADDR:
|
||||||
val=KBD;
|
val=KBD;
|
||||||
|
// We'v read the char, clear B7
|
||||||
bitClear(KBDCR, 7);
|
bitClear(KBDCR, 7);
|
||||||
break;
|
break;
|
||||||
case KBDCR_ADDR:
|
case KBDCR_ADDR:
|
||||||
@ -178,19 +196,24 @@ void handleKeyboard() {
|
|||||||
// KEYBOARD INPUT
|
// KEYBOARD INPUT
|
||||||
if (Serial.available() > 0) {
|
if (Serial.available() > 0) {
|
||||||
char tempKBD = Serial.read();
|
char tempKBD = Serial.read();
|
||||||
|
|
||||||
switch (tempKBD) {
|
switch (tempKBD) {
|
||||||
case 0xA:
|
case 0xA:
|
||||||
|
// Not expected from KEYB
|
||||||
|
// Just ignore
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case 0xD:
|
case 0xD:
|
||||||
|
// CR
|
||||||
tempKBD = 0x0D;
|
tempKBD = 0x0D;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
KBD = tempKBD;
|
KBD = tempKBD;
|
||||||
|
|
||||||
|
// Step B7 on KBD so that the code know a new char is in
|
||||||
bitSet(KBD, 7);
|
bitSet(KBD, 7);
|
||||||
bitSet(KBDCR, 7);
|
bitSet(KBDCR, 7);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +222,7 @@ void setup() {
|
|||||||
pinMode(RW_PIN, INPUT);
|
pinMode(RW_PIN, INPUT);
|
||||||
setupAddressPins();
|
setupAddressPins();
|
||||||
busMode(OUTPUT);
|
busMode(OUTPUT);
|
||||||
Serial.begin (115200);
|
Serial.begin(SERIAL_SPEED);
|
||||||
|
|
||||||
Serial.println("----------------------------");
|
Serial.println("----------------------------");
|
||||||
Serial.println("APPLE 1 REPLICA by =STID=");
|
Serial.println("APPLE 1 REPLICA by =STID=");
|
||||||
@ -218,7 +241,6 @@ void setup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loop () {
|
void loop () {
|
||||||
|
|
||||||
// LOW CLOCK
|
// LOW CLOCK
|
||||||
digitalWrite(CLOCK_PIN, LOW);
|
digitalWrite(CLOCK_PIN, LOW);
|
||||||
delayMicroseconds(CLOCK_DELAY);
|
delayMicroseconds(CLOCK_DELAY);
|
||||||
@ -234,16 +256,18 @@ void loop () {
|
|||||||
readAddress();
|
readAddress();
|
||||||
|
|
||||||
// READ OR WRITE TO BUS?
|
// READ OR WRITE TO BUS?
|
||||||
if (rw_state) {
|
|
||||||
writeToDataBus();
|
if (pre_address != address || pre_rw_state != rw_state) {
|
||||||
|
rw_state ? writeToDataBus() : readFromDataBus();
|
||||||
} else {
|
} else {
|
||||||
readFromDataBus();
|
pre_address = address;
|
||||||
|
pre_rw_state = rw_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleKeyboard();
|
handleKeyboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
// WOZ TEST
|
// WOZ TEST (As on the Apple 1 Manual)
|
||||||
// 0:A9 9 AA 20 EF FF E8 8A 4C 2 0
|
// 0:A9 9 AA 20 EF FF E8 8A 4C 2 0
|
||||||
|
|
||||||
// HELLO WORLD
|
// HELLO WORLD
|
||||||
|
Loading…
x
Reference in New Issue
Block a user