First commit
This commit is contained in:
commit
f614cffe86
|
@ -0,0 +1,6 @@
|
||||||
|
*.xcodeproj
|
||||||
|
*.hex
|
||||||
|
*.elf
|
||||||
|
*.o
|
||||||
|
*.bin
|
||||||
|
*.label
|
|
@ -0,0 +1,32 @@
|
||||||
|
|
||||||
|
GAL20V8
|
||||||
|
EQN2JED - Boolean Equations to JEDEC file assembler (Version V101)
|
||||||
|
Copyright (c) National Semiconductor Corporation 1990-1993
|
||||||
|
Assembled from "d:/ADDRES~1.EQN". Date: 3-31-120
|
||||||
|
*
|
||||||
|
NOTE PINS RW:2 A0:3 A1:4 A2:5 A3:6 A4:7 A5:8 A6:9 A7:10 A8:11*
|
||||||
|
NOTE PINS GND:12 A9:14 A10:15 A11:16 SR:17 RD:18 WD:19 ROM:20*
|
||||||
|
NOTE PINS NC1:21 NC2:22 R:23 VCC:24*
|
||||||
|
NOTE GALMODE SMALL*
|
||||||
|
QF2706*QP24*F0*
|
||||||
|
L0640
|
||||||
|
1111111011111111111111111111111111110111
|
||||||
|
1111111011111111111111111111111111011111
|
||||||
|
1111111011111111111111111111110111111111
|
||||||
|
1111111011111111111111111101111111111111*
|
||||||
|
L0960
|
||||||
|
1011011010111011101110111010101001101011*
|
||||||
|
L1280
|
||||||
|
0111101010111011101110111010101001101011*
|
||||||
|
L1600
|
||||||
|
0111101010111011101110111010101010101011*
|
||||||
|
L2560
|
||||||
|
11011100*
|
||||||
|
L2632
|
||||||
|
00000011*
|
||||||
|
L2640
|
||||||
|
0000000000000000111100001000000010000000100000000000000000000000*
|
||||||
|
L2704
|
||||||
|
10*
|
||||||
|
C1C79*
|
||||||
|
0000
|
|
@ -0,0 +1,20 @@
|
||||||
|
chip GAL20V8
|
||||||
|
|
||||||
|
NC3=1 RW=2 A0=3 A1=4 A2=5 A3=6 A4=7 A5=8 A6=9 A7=10 A8=11 GND=12
|
||||||
|
A9=14 A10=15 A11=16 SR=17 RD=18 WD=19 ROM=20
|
||||||
|
R=23 VCC=24
|
||||||
|
|
||||||
|
NC1=21 NC2=22
|
||||||
|
|
||||||
|
equations
|
||||||
|
|
||||||
|
NC1=gnd
|
||||||
|
NC2=gnd
|
||||||
|
|
||||||
|
SR = /A0 * /A1 * /A2 * /A3 * /A4 * /A5 * /A6 * /A7 * /A8 * /A9 * /A10 * /A11 * /R * RW
|
||||||
|
RD = /A0 * /A1 * /A2 * /A3 * /A4 * /A5 * /A6 * A7 * /A8 * /A9 * /A10 * /A11 * /R * RW
|
||||||
|
WD = A0 * /A1 * /A2 * /A3 * /A4 * /A5 * /A6 * A7 * /A8 * /A9 * /A10 * /A11 * /R * /RW
|
||||||
|
/ROM = A8 * /R * RW
|
||||||
|
+ A9 * /R * RW
|
||||||
|
+ A10 * /R * RW
|
||||||
|
+ A11 * /R * RW
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
xa -W -C -v -O ASCII -c src/apple1serial.xa -l apple1serial.label -o apple1serial.bin
|
|
@ -0,0 +1,53 @@
|
||||||
|
# Name: apple1serial
|
||||||
|
# Author: flovenol@gmail.com
|
||||||
|
|
||||||
|
DEVICE = atmega328p
|
||||||
|
CLOCK = 16000000
|
||||||
|
PROGRAMMER = -c stk500v2 -P /dev/tty.usbmodemavrdope1
|
||||||
|
OBJECTS = main.o
|
||||||
|
|
||||||
|
# For computing fuse byte values for other devices and options see
|
||||||
|
# the fuse bit calculator at http://www.engbedded.com/fusecalc/
|
||||||
|
FUSES = -U hfuse:w:0xde:m -U lfuse:w:0xff:m -U efuse:w:0xfd:m
|
||||||
|
|
||||||
|
AVRDUDE = avrdude $(PROGRAMMER) -p $(DEVICE)
|
||||||
|
COMPILE = avr-gcc -Wall -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE)
|
||||||
|
|
||||||
|
all: main.hex
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(COMPILE) -c $< -o $@
|
||||||
|
|
||||||
|
.S.o:
|
||||||
|
$(COMPILE) -x assembler-with-cpp -c $< -o $@
|
||||||
|
|
||||||
|
.c.s:
|
||||||
|
$(COMPILE) -S $< -o $@
|
||||||
|
|
||||||
|
flash: all
|
||||||
|
$(AVRDUDE) -U flash:w:main.hex:i
|
||||||
|
|
||||||
|
fuse:
|
||||||
|
$(AVRDUDE) $(FUSES)
|
||||||
|
|
||||||
|
install: flash fuse
|
||||||
|
|
||||||
|
load: all
|
||||||
|
bootloadHID main.hex
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f main.hex main.elf $(OBJECTS)
|
||||||
|
|
||||||
|
main.elf: $(OBJECTS)
|
||||||
|
$(COMPILE) -o main.elf $(OBJECTS)
|
||||||
|
|
||||||
|
main.hex: main.elf
|
||||||
|
rm -f main.hex
|
||||||
|
avr-objcopy -j .text -j .data -O ihex main.elf main.hex
|
||||||
|
avr-size --format=avr --mcu=$(DEVICE) main.elf
|
||||||
|
|
||||||
|
disasm: main.elf
|
||||||
|
avr-objdump -d main.elf
|
||||||
|
|
||||||
|
cpp:
|
||||||
|
$(COMPILE) -E main.c
|
|
@ -0,0 +1,177 @@
|
||||||
|
#ifndef F_CPU
|
||||||
|
#define F_CPU 16000000UL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BAUD 9600
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <util/setbaud.h>
|
||||||
|
|
||||||
|
#define DATA_READ_LINE PB0
|
||||||
|
#define DATA_WRITE_LINE PD7
|
||||||
|
#define STATUS PD6
|
||||||
|
|
||||||
|
#define DATA0 PB1
|
||||||
|
#define DATA1 PB2
|
||||||
|
#define DATA2 PB3
|
||||||
|
#define DATA3 PB4
|
||||||
|
#define DATA4 PB5
|
||||||
|
#define DATA5 PD2
|
||||||
|
#define DATA6 PD3
|
||||||
|
#define DATA7 PD4
|
||||||
|
|
||||||
|
typedef enum {NONE, READ, WRITE} mode_t;
|
||||||
|
mode_t mode = NONE;
|
||||||
|
|
||||||
|
uint8_t data = 0x00;
|
||||||
|
uint8_t upper_part = 0x00;
|
||||||
|
uint8_t lower_part = 0x00;
|
||||||
|
|
||||||
|
uint8_t data_write_interrupt_count = 0;
|
||||||
|
uint8_t data_read_interrupt_count = 0;
|
||||||
|
|
||||||
|
// Registers: PCMSK0, PCMSK1, PCMSK2 :registers that enable or disable pin-change interrupts
|
||||||
|
// on individual pins
|
||||||
|
|
||||||
|
// PCICR : a register where the three least significant bits enable or disable pin change interrupts
|
||||||
|
// on a range of pins, i.e. {0,0,0,0,0,PCIE2,PCIE1,PCIE0}, where PCIE2 maps to PCMSK2, PCIE1 maps to PCMSK1,
|
||||||
|
// and PCIE0 maps to PCMSK0.
|
||||||
|
|
||||||
|
inline void ready() {
|
||||||
|
PORTD |= _BV(STATUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void not_ready() {
|
||||||
|
PORTD &= ~(_BV(STATUS));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
|
||||||
|
// set input on DATA_READ_LINE
|
||||||
|
DDRB &= ~(_BV(DATA_READ_LINE));
|
||||||
|
// interrupt on DATA_READ_LINE change
|
||||||
|
PCMSK0 |= _BV(PCINT0);
|
||||||
|
PCICR |= _BV(PCIE0);
|
||||||
|
|
||||||
|
// set input on DATA_WRITE_LINE
|
||||||
|
DDRD &= ~(_BV(DATA_WRITE_LINE));
|
||||||
|
// interrupt on DATA_WRITE_LINE change
|
||||||
|
PCMSK2 |= _BV(PCINT23);
|
||||||
|
PCICR |= _BV(PCIE2);
|
||||||
|
|
||||||
|
UBRR0H = UBRRH_VALUE;
|
||||||
|
UBRR0L = UBRRL_VALUE;
|
||||||
|
|
||||||
|
UCSR0A = 0x00;
|
||||||
|
UCSR0C = 0x00;
|
||||||
|
// 8 bits of data, 1 stop bit, no parity
|
||||||
|
UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
|
||||||
|
// TXD pullup
|
||||||
|
PORTD |= _BV(PD1);
|
||||||
|
|
||||||
|
// interrupt on DATA_READ_LINE change
|
||||||
|
PCMSK0 |= _BV(PCINT0);
|
||||||
|
PCICR |= _BV(PCIE0);
|
||||||
|
|
||||||
|
// set output on status
|
||||||
|
DDRD |= _BV(STATUS);
|
||||||
|
not_ready();
|
||||||
|
|
||||||
|
// enable global interrupts
|
||||||
|
sei();
|
||||||
|
}
|
||||||
|
|
||||||
|
// data read line
|
||||||
|
ISR(PCINT0_vect) {
|
||||||
|
if (data_read_interrupt_count == 0) {
|
||||||
|
if (mode != READ) {
|
||||||
|
mode = READ;
|
||||||
|
|
||||||
|
// enable RXD and it's interrupt
|
||||||
|
UCSR0B = _BV(RXEN0) | _BV(RXCIE0);
|
||||||
|
|
||||||
|
// set output on data pins
|
||||||
|
DDRD |= _BV(DATA5) | _BV(DATA6) | _BV(DATA7);
|
||||||
|
DDRB |= _BV(DATA0) | _BV(DATA1) | _BV(DATA2) | _BV(DATA3) | _BV(DATA4);
|
||||||
|
}
|
||||||
|
not_ready();
|
||||||
|
data_read_interrupt_count = 1;
|
||||||
|
} else {
|
||||||
|
data_read_interrupt_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// data write line
|
||||||
|
ISR(PCINT2_vect) {
|
||||||
|
upper_part = PINB;
|
||||||
|
lower_part = PIND;
|
||||||
|
|
||||||
|
if (data_write_interrupt_count == 0) {
|
||||||
|
if (mode == WRITE) {
|
||||||
|
upper_part = upper_part >> 1;
|
||||||
|
upper_part &= 0x1f;
|
||||||
|
|
||||||
|
lower_part = lower_part << 3;
|
||||||
|
lower_part &= 0xe0;
|
||||||
|
|
||||||
|
// set status to not ready
|
||||||
|
PORTD &= ~(_BV(STATUS));
|
||||||
|
|
||||||
|
// send byte
|
||||||
|
loop_until_bit_is_set(UCSR0A, UDRE0);
|
||||||
|
UDR0 = upper_part | lower_part;
|
||||||
|
} else {
|
||||||
|
if (mode == READ) {
|
||||||
|
// zero all outputs
|
||||||
|
PORTD &= 0xe3;
|
||||||
|
PORTB &= 0xc1;
|
||||||
|
}
|
||||||
|
mode = WRITE;
|
||||||
|
|
||||||
|
// enable TXD interrupt and it's interrupt
|
||||||
|
UCSR0B = _BV(TXEN0) | _BV(TXCIE0);
|
||||||
|
|
||||||
|
// set input on data pins
|
||||||
|
DDRD &= ~(_BV(DATA5) | _BV(DATA6) | _BV(DATA7));
|
||||||
|
DDRB &= ~(_BV(DATA0) | _BV(DATA1) | _BV(DATA2) | _BV(DATA3) | _BV(DATA4));
|
||||||
|
|
||||||
|
ready();
|
||||||
|
}
|
||||||
|
data_write_interrupt_count = 1;
|
||||||
|
} else {
|
||||||
|
data_write_interrupt_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(USART_RX_vect)
|
||||||
|
{
|
||||||
|
if (mode == READ) {
|
||||||
|
data = UDR0;
|
||||||
|
|
||||||
|
upper_part = (PORTD & 0xe3) | ((0xe0 & data)>>3);
|
||||||
|
lower_part = (PORTB & 0xc1) | ((0x1f & data)<<1);
|
||||||
|
|
||||||
|
PORTD = upper_part;
|
||||||
|
PORTB = lower_part;
|
||||||
|
|
||||||
|
ready();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(USART_TX_vect)
|
||||||
|
{
|
||||||
|
if (mode == WRITE) {
|
||||||
|
ready();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
setup();
|
||||||
|
|
||||||
|
for(;;){
|
||||||
|
// only interrupt driven
|
||||||
|
}
|
||||||
|
return 0; /* never reached */
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,204 @@
|
||||||
|
#define hex1l $50 ;End address of dump block
|
||||||
|
#define hex1h $51
|
||||||
|
#define hex2l $52 ;Begin address of dump block
|
||||||
|
#define hex2h $53
|
||||||
|
|
||||||
|
#define input $0200 ;Input buffer
|
||||||
|
#define kbd_data $D010 ;PIA.A keyboard input
|
||||||
|
#define kbd_cr $D011 ;PIA.A keyboard control register
|
||||||
|
#define monitor $FF1A ;Escape back to monitor
|
||||||
|
#define echo $FFEF ;Echo character to terminal
|
||||||
|
#define prbyte $FFDC
|
||||||
|
|
||||||
|
#define serial_ready $C000 ;Serial status
|
||||||
|
#define serial_read $C080 ;Data read address
|
||||||
|
#define serial_write $C081 ;Data write address
|
||||||
|
|
||||||
|
;-------------------------------------------------------------------------
|
||||||
|
; Constants
|
||||||
|
;-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define R_LETTER $D2
|
||||||
|
#define W_LETTER $D7
|
||||||
|
#define ZERO $B0
|
||||||
|
#define SEP $AE
|
||||||
|
#define CR $8D ;Carriage Return
|
||||||
|
#define ESC $9B ;ASCII ESC
|
||||||
|
#define SPACE $A0
|
||||||
|
|
||||||
|
; pad first 256 bytes with zeroes
|
||||||
|
.dsb 256, 0
|
||||||
|
|
||||||
|
; this section is almost identical to original WOZ ACI
|
||||||
|
; adapted from https://www.sbprojects.net/projects/apple1/aci.php
|
||||||
|
* = $C100
|
||||||
|
apple_serial
|
||||||
|
lda #CR ;Drop the cursor one line
|
||||||
|
jsr echo
|
||||||
|
lda #"*" ;Print prompt
|
||||||
|
jsr echo
|
||||||
|
lda #CR ;And drop the cursor one line
|
||||||
|
jsr echo
|
||||||
|
ldy #$FF ;Reset the input buffer index
|
||||||
|
|
||||||
|
next_char
|
||||||
|
iny
|
||||||
|
|
||||||
|
kbd_wait
|
||||||
|
lda kbd_cr ;Wait for a key
|
||||||
|
bpl kbd_wait ;Still no key!
|
||||||
|
|
||||||
|
lda kbd_data ;Read key from keyboard
|
||||||
|
sta $0200,Y ;Save it into buffer
|
||||||
|
jsr echo ;And type it on the screen
|
||||||
|
cmp #ESC
|
||||||
|
beq apple_serial ;Start from scratch if ESC!
|
||||||
|
cmp #CR
|
||||||
|
bne next_char ;Read keys until CR
|
||||||
|
|
||||||
|
ldx #$FF ;Initialize parse buffer pointer
|
||||||
|
|
||||||
|
;-------------------------------------------------------------------------
|
||||||
|
; Start parsing first or a new tape command
|
||||||
|
;-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
next_cmd
|
||||||
|
lda #$00 ;Clear begin and end values
|
||||||
|
sta hex1l
|
||||||
|
sta hex1h
|
||||||
|
sta hex2l
|
||||||
|
sta hex2h
|
||||||
|
|
||||||
|
next_chr
|
||||||
|
inx ;Increment input pointer
|
||||||
|
lda $0200,X ;Get next char from input lin
|
||||||
|
cmp #R_LETTER ;Read command?
|
||||||
|
beq read ;Yes!
|
||||||
|
cmp #W_LETTER ;Write command?
|
||||||
|
beq write ;Yes! (note: CY=1)
|
||||||
|
cmp #SEP ;Separator?
|
||||||
|
beq separator ;Yes!
|
||||||
|
cmp #CR ;End of line?
|
||||||
|
beq to_monitor ;Escape to monitor! We're done
|
||||||
|
cmp #SPACE ;Ignore spaces
|
||||||
|
beq next_chr
|
||||||
|
eor #ZERO ;Map digits to 0-9
|
||||||
|
cmp #$0A ;Is it a decimal digit?
|
||||||
|
bcc digit ;Yes!
|
||||||
|
clc
|
||||||
|
adc #$89 ;Map letter "A"-"F" to $FA-$FF
|
||||||
|
cmp #$FA ;Hex letter?
|
||||||
|
bcc apple_serial ;No! Character not hex!
|
||||||
|
|
||||||
|
digit
|
||||||
|
asl ;Hex digit to MSD of A
|
||||||
|
asl
|
||||||
|
asl
|
||||||
|
asl
|
||||||
|
|
||||||
|
ldy #4 ;Shift count
|
||||||
|
|
||||||
|
hexshift
|
||||||
|
asl ;Hex digit left, MSB to carry
|
||||||
|
rol hex1l ;Rotate into LSD
|
||||||
|
rol hex1h ;Rotate into MSD
|
||||||
|
dey ;Done 4 shifts?
|
||||||
|
bne hexshift ;No! Loop
|
||||||
|
beq next_chr ;Handle next character
|
||||||
|
|
||||||
|
;-------------------------------------------------------------------------
|
||||||
|
; Return to monitor, prints \ first
|
||||||
|
;-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
to_monitor
|
||||||
|
jmp monitor ;Escape back to monitor
|
||||||
|
|
||||||
|
;-------------------------------------------------------------------------
|
||||||
|
; Separating . found. Copy HEX1 to Hex2. Doesn't clear HEX1!!!
|
||||||
|
;-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
separator
|
||||||
|
lda hex1l ;Copy hex value 1 to hex value 2
|
||||||
|
sta hex2l
|
||||||
|
lda hex1h
|
||||||
|
sta hex2h
|
||||||
|
lda #$00 ;Original ACI bug (not enough ROM space?) fix
|
||||||
|
sta hex1l
|
||||||
|
sta hex1h
|
||||||
|
jmp next_chr ;Always taken!
|
||||||
|
|
||||||
|
;-------------------------------------------------------------------------
|
||||||
|
; Read procedure
|
||||||
|
;-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
read
|
||||||
|
lda serial_read ;Enable read mode
|
||||||
|
ldy #$00
|
||||||
|
|
||||||
|
read_byte
|
||||||
|
lda serial_ready
|
||||||
|
beq read_byte ;No data arrived
|
||||||
|
lda serial_read ;Read byte
|
||||||
|
sta ($52),Y ;Store byte under address
|
||||||
|
|
||||||
|
lda hex2l
|
||||||
|
cmp hex1l ;Compare lower destination address half with lower end address half
|
||||||
|
bne read_next ;If not equal then increment destination address
|
||||||
|
|
||||||
|
lda hex2h
|
||||||
|
cmp hex1h ;Compare upper destination address half with upper end address half
|
||||||
|
bne read_next ;If not equal then proceed to read next byte
|
||||||
|
|
||||||
|
jmp next_cmd ;Read is completed, proceed to next command
|
||||||
|
|
||||||
|
read_next
|
||||||
|
ldx #hex2l
|
||||||
|
jsr increment_16bit ;Increment destination address
|
||||||
|
jmp read_byte
|
||||||
|
|
||||||
|
;-------------------------------------------------------------------------
|
||||||
|
; Write procedure
|
||||||
|
;-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
write
|
||||||
|
lda serial_read ;Enable read mode to be sure that we are in "fresh" write mode
|
||||||
|
sta serial_write ;Enable write mode
|
||||||
|
ldy #$00
|
||||||
|
|
||||||
|
write_byte
|
||||||
|
lda serial_ready
|
||||||
|
beq write_byte
|
||||||
|
lda ($52),Y
|
||||||
|
sta serial_write
|
||||||
|
|
||||||
|
lda hex2l
|
||||||
|
cmp hex1l ;Compare lower destination address half with lower end address half
|
||||||
|
bne write_next ;If not equal then increment destination address
|
||||||
|
|
||||||
|
lda hex2h
|
||||||
|
cmp hex1h ;Compare upper destination address half with upper end address half
|
||||||
|
bne write_next ;If not equal then proceed to write next byte
|
||||||
|
|
||||||
|
jmp next_cmd ;Read is completed, proceed to next command
|
||||||
|
|
||||||
|
write_next
|
||||||
|
ldx #hex2l
|
||||||
|
jsr increment_16bit ;Increment destination address
|
||||||
|
jmp write_byte
|
||||||
|
|
||||||
|
;-------------------------------------------------------------------------
|
||||||
|
; tool routines
|
||||||
|
;-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
increment_16bit
|
||||||
|
inc $00,X
|
||||||
|
bne increment_16bit_done
|
||||||
|
inx
|
||||||
|
inc $00,X
|
||||||
|
increment_16bit_done
|
||||||
|
rts
|
||||||
|
|
||||||
|
;-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
end_of_apple1serial
|
||||||
|
;#include "src/tests.xa"
|
|
@ -0,0 +1,67 @@
|
||||||
|
#define echo $FFEF
|
||||||
|
#define kbd_data $D010
|
||||||
|
#define kbd_cr $D011
|
||||||
|
#define serial_ready $C000
|
||||||
|
#define serial_read $C080
|
||||||
|
#define serial_write $C081
|
||||||
|
|
||||||
|
* = $C200
|
||||||
|
.dsb (*-end_of_apple1serial), 0
|
||||||
|
|
||||||
|
; teletype on apple-1
|
||||||
|
* = $C200
|
||||||
|
teletype_apple1 = $C200
|
||||||
|
lda serial_read
|
||||||
|
wait
|
||||||
|
lda serial_ready
|
||||||
|
beq wait
|
||||||
|
lda serial_read
|
||||||
|
jsr echo
|
||||||
|
jmp wait
|
||||||
|
end_of_teletype_apple1
|
||||||
|
|
||||||
|
; AD 80 C0 AD 00 C0 F0 FB
|
||||||
|
; AD 80 C0 20 EF FF 4C 03
|
||||||
|
; 00
|
||||||
|
|
||||||
|
; teletype on remote
|
||||||
|
* = $C300
|
||||||
|
.dsb (*-end_of_teletype_apple1), 0
|
||||||
|
|
||||||
|
* = $C300
|
||||||
|
teletype_remote = $C300
|
||||||
|
lda #$FF
|
||||||
|
sta serial_write
|
||||||
|
get_key
|
||||||
|
lda kbd_cr
|
||||||
|
bpl get_key
|
||||||
|
lda kbd_data
|
||||||
|
sec
|
||||||
|
sbc #$A0
|
||||||
|
sta serial_write
|
||||||
|
jmp get_key
|
||||||
|
end_of_teletype_remote
|
||||||
|
|
||||||
|
; A9 FF 8D 81 C0 AD 11 D0
|
||||||
|
; 10 FB AD 10 D0 38 E9 A0
|
||||||
|
; 8D 81 C0 4C 85 02
|
||||||
|
|
||||||
|
; 0-255 repeating counter over TXD
|
||||||
|
* = $C400
|
||||||
|
.dsb (*-end_of_teletype_remote), 0
|
||||||
|
|
||||||
|
* = $C400
|
||||||
|
counter_remote = $C400
|
||||||
|
ldy #$00
|
||||||
|
sta serial_write
|
||||||
|
check_ready
|
||||||
|
lda serial_ready
|
||||||
|
beq check_ready
|
||||||
|
tya
|
||||||
|
sta serial_write
|
||||||
|
iny
|
||||||
|
jmp check_ready
|
||||||
|
|
||||||
|
; A0 00 8D 81 C0 AD 00 C0
|
||||||
|
; F0 FB 98 8D 81 C0 C8 4C
|
||||||
|
; 85 02
|
Loading…
Reference in New Issue