2021-10-21 07:59:53 +00:00
.feature string_escapes ; Allow c-style string escapes when using ca65
.feature org_per_seg
2022-09-18 12:02:18 +00:00
.feature c_comments
2022-10-18 09:00:00 +00:00
.export I2 C A D D R , I 2 C R E G , i 2 c _ r e a d , i 2 c _ t e s t , m a i n , k b _ r p t r , P R I M M , p r i n t k , p r i n t b y t e , w k e y , P O R T B , T I M E O U T ,e x i t i r q , p r i n t a , n e w l i n e , s e t p u l s e s , s c r p , s c w p , s i m p l e d e l a y , s e l e c t b a u d r a t e , M I L L I S H ,r e s e t k b , c l r s c n ,c h e c k k e y b o a r d , k b _ b u f f e r , M O N R D K E Y ,C R S R P N T , t 2 i r q r e g 1 , M I L L I S
2022-09-18 12:02:18 +00:00
;BASIC := 1 ; 1 if BASIC is enabled
;DEBUG = 1
2022-05-27 15:52:45 +00:00
PORTB = $ 6 0 0 0 ; PB0: SCK/SCL, PB1: RF CS, PB2: RF CE, PB3: SDA, PB4,PB5: MISO ,PB6: PS/2 Clock In, PB7: MOSI/T1 Out (Tape drive output)
2021-10-21 07:59:53 +00:00
PORTA = $ 6 0 0 1
DDRB = $ 6 0 0 2
DDRA = $ 6 0 0 3
T1 C L = $ 6 0 0 4
T1 C H = $ 6 0 0 5
T1 L L = $ 6 0 0 6
T1 L H = $ 6 0 0 7
T2 C L = $ 6 0 0 8
T2 C H = $ 6 0 0 9
SR1 = $ 6 0 0 A
2022-05-27 15:52:45 +00:00
ACR = $ 6 0 0 B ; [7] PB.7 T1 OUT, [6] T1 mode , [5] T2, [4:2] Shift register control, [1] PB Latch enable, [0] PA Latch Enable
2022-04-03 12:13:47 +00:00
PCR = $ 6 0 0 C ; [7:5] CB2 Control, [4] CBl Control, [3:1] CA2 Control, [0] CAl Control
IFR = $ 6 0 0 D ; [7:0] IRQ Tl T2 CBl CB2 SR CA1 CA2
IER = $ 6 0 0 E ; [7:0] S/C Tl T2 CBl CB2 SR CA1 CA2
2021-10-21 07:59:53 +00:00
PORTANHS = $ 6 0 0 F
2022-10-18 09:00:00 +00:00
CTRL = $ 7 0 0 0
2021-10-21 07:59:53 +00:00
2022-09-18 12:02:18 +00:00
TIMEOUT = 7 9 9 8 ; Should be around 2ms
2021-10-21 07:59:53 +00:00
RELEASE = % 0 0 0 0 0 0 0 1
SHIFT = % 0 0 0 0 0 0 1 0
2022-04-03 12:13:47 +00:00
ECODE = % 0 0 0 0 0 1 0 0
CRSR = % 0 1 0 0 0 0 0 0
CRSRF = % 1 0 0 0 0 0 0 0
2022-05-27 15:52:45 +00:00
KTIMEOUT= % 0 0 1 0 0 0 0 0
2022-07-21 19:36:36 +00:00
DBGFLAG = % 0 0 0 1 0 0 0 0
2021-10-21 07:59:53 +00:00
2022-09-18 12:02:18 +00:00
kb_ b u f f e r = $ 0 2 0 0 ; 128-byte kb buffer 0200-0280
scbuf = $ 0 2 8 0 ; Scan code buffer
USERLANDH = $ 0 3 ; RAM page userland code starts
; Screen constants
SCREENSTARTH = $ 0 8 ; Change this to the page your Video RAM starts! (VRAM at $0800 requires a few jumpers to change from the default $2000 - this will change in the next build of R1)
SCREENSTARTL = $ 4 c ; Top left of screen - may differ between VGA screens
LINESTART = $ 0 c
LINEEND = $ 3 E
NUMLINES = 2 8
2021-10-21 07:59:53 +00:00
2022-04-03 12:13:47 +00:00
;Custom keyboard mappings
DN_ A R R _ K E Y = $ F 3
UP_ A R R _ K E Y = $ F 4
PGUP_ K E Y = $ F 6
PGDN_ K E Y = $ F 5
L_ A R R _ K E Y = $ F 2
R_ A R R _ K E Y = $ F 1
HOME_ K E Y = $ F 0
ESC_ K E Y = $ 1 b
2022-07-21 19:36:36 +00:00
PRTSC_ K E Y = $ E F
F1 2 _ K E Y = $ E C
F1 1 _ K E Y = $ E B
F1 0 _ K E Y = $ E A
F9 _ K E Y = $ E 9
2022-09-18 12:02:18 +00:00
movedfromzp = s c b u f + 8
brkcnt = m o v e d f r o m z p
RF_ S T S = m o v e d f r o m z p + 1
MONCNT = m o v e d f r o m z p + 2
TMP = m o v e d f r o m z p + 3 ;
TMP2 = m o v e d f r o m z p + 4
RF_ E R R = m o v e d f r o m z p + 5
ERRS = m o v e d f r o m z p + 6
TMP3 = m o v e d f r o m z p + 7
ABUF = m o v e d f r o m z p + 8 ; 8 bytes
;to $2F
;ABUF = $28
TMP4 = m o v e d f r o m z p + 1 6
SVCSR = m o v e d f r o m z p + 1 7
;+1
2022-10-18 09:00:00 +00:00
I2 C A D D R = m o v e d f r o m z p + 1 9
I2 C R E G = m o v e d f r o m z p + 2 0
2022-09-18 12:02:18 +00:00
zp_ s = $ f8
kb_ w p t r = z p _ s
kb_ r p t r = z p _ s + 1
kb_ f l a g s = z p _ s + 2
kb_ l a s t = z p _ s + 3
scwp = z p _ s + 4
scrp = z p _ s + 5
outb = z p _ s + 6
inb = z p _ s + 7
zp_ s2 = $ e 0
MONH = z p _ s2 + 1
MONL = z p _ s2
KEYBOARD = z p _ s2 + 2
SPITMP = z p _ s2 + 3
MILLIS = z p _ s2 + 4
MILLISH = z p _ s2 + 5
CRSRPNT = z p _ s2 + 6
2021-10-21 07:59:53 +00:00
CRSRPNT2 = C R S R P N T + 1
2022-04-03 12:13:47 +00:00
2022-09-18 12:02:18 +00:00
zp_ s3 = $ e 8
SVP = z p _ s3 ; Save pointer
SVPH =zp_s3 + 1
HXH = z p _ s3 + 2
SLB = z p _ s3 + 3 ; Size low byte
SHB = z p _ s3 + 4
CRSRCHR = z p _ s3 + 5
PRIMMZP1 = z p _ s3 + 6
PRIMMZP2 = z p _ s3 + 7
zp_ s4 = $ f0
t2 i r q r e g 1 = z p _ s4
t2 i r q r e g 2 = z p _ s4 + 1
USERLANDP = z p _ s4 + 2 ; JMP Pointer
USERLANDPH = z p _ s4 + 3
DEBUGP = z p _ s4 + 4
DEBUGPH = z p _ s4 + 5
zp_ s5 = $ d8
SCRLPNT = z p _ s5 ; also +1
SCRLPNT2 = z p _ s5 + 2 ; also +3
; Tape constants
KCS3 0 0 P L = 4 ; Kansas City Standard takes 4 1200 Hz pulses for a 0
KCS3 0 0 P H = 8 ; and 8 2400Hz pulses for a 1
; Tape vars
TAPEVARS = m o v e d f r o m z p + 3 2
CBIT = T A P E V A R S
RXBYTE = T A P E V A R S + 1
2022-10-18 09:00:00 +00:00
BITNO = T A P E V A R S + 1 ; Reusing
2022-09-18 12:02:18 +00:00
TAPEFLAGS = T A P E V A R S + 2
PULSES = T A P E V A R S + 3
NRZBYTE = T A P E V A R S + 4
onesinarow = T A P E V A R S + 5
plsperiod = T A P E V A R S + 6 ; also +7
PULSESL = T A P E V A R S + 8 ; Config variable if we do something other than KCS
PULSESH = T A P E V A R S + 9 ; ^^
plzpnt = z p _ s4 + 6 ; also +7
CT1 L = T A P E V A R S + 1 0
CT1 H = T A P E V A R S + 1 1
LT1 L = T A P E V A R S + 1 2
LT1 H = T A P E V A R S + 1 3
LOADTIMEOUT = T A P E V A R S + 1 4
2022-04-03 12:13:47 +00:00
; CE = $69
2022-09-18 12:02:18 +00:00
MSGBUF = T A P E V A R S + 1 5
;+32bytes == To
RF2 4 R E G S = M S G B U F + 3 2
2022-04-03 12:13:47 +00:00
2021-10-21 07:59:53 +00:00
uservia = P O R T B
2022-05-27 15:52:45 +00:00
mosi = % 1 0 0 0 0 0 0 0
miso = % 0 0 1 0 0 0 0 0
SDA = 8 ; PB3 bitmask
SDA_ I N V = $ F 7
2022-10-18 09:00:00 +00:00
SCL = 1 6 ; PB4 bitmask
SCL_ I N V = $ E F
2021-10-21 07:59:53 +00:00
.segment " RODATA"
2022-04-03 12:13:47 +00:00
;.org $8000 ; Not strictly needed with CA65 but shows correct address in listing.txt
.list on ; Does this work?
2021-10-21 07:59:53 +00:00
nmi :
reset :
cld ; Because you never know
;CLEAR RAM
2022-09-18 12:02:18 +00:00
sei ; In case this was not a hw reset
2021-10-21 07:59:53 +00:00
ldx #$ 0
lda #0
2022-09-18 12:02:18 +00:00
clearzp :
2021-10-21 07:59:53 +00:00
sta $ 0 0 ,x
inx
2022-09-18 12:02:18 +00:00
bne c l e a r z p
2021-10-21 07:59:53 +00:00
2022-04-03 12:13:47 +00:00
;Assumes x and A are 0 from above
clearstack :
sta $ 0 1 0 0 ,x
inx
bne c l e a r s t a c k
2022-09-18 12:02:18 +00:00
clearp2 :
sta $ 0 2 0 0 ,x
inx
bne c l e a r p2
clearp3 :
sta $ 0 3 0 0 ,x
inx
bne c l e a r p3
2022-04-03 12:13:47 +00:00
2022-09-18 12:02:18 +00:00
ldx #$ F F
txs
2022-05-27 15:52:45 +00:00
2021-10-21 07:59:53 +00:00
2022-09-18 12:02:18 +00:00
noclear : ;Soft reset point - BRK
2021-10-21 07:59:53 +00:00
2022-04-03 12:13:47 +00:00
jsr c l r s c n
2022-09-18 12:02:18 +00:00
lda #$ F 1
sta C T R L
2021-10-21 07:59:53 +00:00
lda #S C R E E N S T A R T L
sta C R S R P N T
lda #S C R E E N S T A R T H
sta C R S R P N T 2
2022-05-27 15:52:45 +00:00
;lda #2
;sta PORTB ; Set SPI CS high
lda #% 10010111 ; Port B DDR for SPI
2021-10-21 07:59:53 +00:00
sta D D R B
2022-05-27 15:52:45 +00:00
lda #0
2022-07-21 19:36:36 +00:00
sta D D R A ; Port A all inputs
2021-10-21 07:59:53 +00:00
sta k b _ r p t r ; Init keyboard pointers before enabling interrupts
sta k b _ w p t r
2022-04-03 12:13:47 +00:00
sta R F _ E R R ; Reset RF error
2022-09-18 12:02:18 +00:00
;cli ; Enable interrupts
2022-05-27 15:52:45 +00:00
lda #% 11000000 ; Set T1
sta I E R
LDA #% 01000000
STA A C R ; T1 continuous, PB7 disabled
2022-09-18 12:02:18 +00:00
2022-05-27 15:52:45 +00:00
LDA #< T I M E O U T
STA T 1 C L ; Set low byte of timer1 counter
LDA #> T I M E O U T
STA T 1 C H ; Set high byte of timer1 counter
2022-04-03 12:13:47 +00:00
ldx #$ 10 ; Read first tx addr byte = should be default, if not then no module connected
2022-09-18 12:02:18 +00:00
stx k b _ f l a g s ; Debug enabled
2022-04-03 12:13:47 +00:00
jsr r w _ r e g
cmp #$ E 7
2022-05-27 15:52:45 +00:00
bne n o r f m o d u l e
jsr i n i t r f24
bne w e l c o m e ; BRA
norfmodule :
;debug, disable RF
2022-04-03 12:13:47 +00:00
inc R F _ E R R ; No module, set RF_ERR
welcome :
jsr P R I M M
message : .asciiz " GREETINGS PROFESSOR FALKEN.", "\n", "SHALL WE PLAY A GAME?", "\n "
2021-10-21 07:59:53 +00:00
2022-04-03 12:13:47 +00:00
welcomedone :
2022-05-27 15:52:45 +00:00
;Let's enable the keyboard
2022-09-18 12:02:18 +00:00
lda #$ 91
sta C T R L
jsr r e s e t k b
lda #1
sta C T R L
2022-05-27 15:52:45 +00:00
cli
main : ; loop
2022-04-03 12:13:47 +00:00
lda R F _ E R R
bne s k i p r f
bit A C R ; If ACR.7 is set then we can't use SPI since MOSI is outputting TM1.
bpl r f s t u f f
skiprf :
jmp n o m s g
rfstuff :
;jsr readrf24regs ; Debug - we can also just do an rf_nop to read rf24 status (RF_STS)
jsr r f _ n o p ; Not debug
;If msg received, put it in MSGBUF
bit R F _ S T S
bvs g t g m ; Check irq
lda R F _ S T S
cmp #$ 0 e ; Check if fifo empty
bne g t g m
2022-07-21 19:36:36 +00:00
;lda SLB
;bne nextpacket
2022-04-03 12:13:47 +00:00
jmp n o m s g ; No msg received
gtgm :
jsr g e t m e s s a g e
2022-09-18 12:02:18 +00:00
lda M S G B U F
2022-04-03 12:13:47 +00:00
bne d a t a p a c k e t ; Check for control message
2022-09-18 12:02:18 +00:00
lda M S G B U F + 1
2022-04-03 12:13:47 +00:00
cmp #$ 31 ; Trust but verify
beq c t r l m s g
jsr i n i t r f24 ; Junk package. Reset radio.
jmp n o m s g
2022-07-21 19:36:36 +00:00
2022-04-03 12:13:47 +00:00
ctrlmsg :
2022-09-18 12:02:18 +00:00
lda M S G B U F + 2
2022-07-21 19:36:36 +00:00
sta S L B ; Data size low byte
2022-09-18 12:02:18 +00:00
lda M S G B U F + 3
2022-07-21 19:36:36 +00:00
sta S H B ; Data size high byte
2022-04-03 12:13:47 +00:00
jsr P R I M M
.asciiz " Receiving $ "
2022-07-21 19:36:36 +00:00
lda S H B
2022-04-03 12:13:47 +00:00
jsr p r i n t b y t e
2022-07-21 19:36:36 +00:00
lda S L B
2022-04-03 12:13:47 +00:00
jsr p r i n t b y t e
jsr P R I M M
.asciiz " bytes. \ n "
2022-07-21 19:36:36 +00:00
inc S H B
lda #0
sta S V P
2022-09-18 12:02:18 +00:00
lda #U S E R L A N D H
sta S V P H ; Save pointer starts at #USERLANDH
2022-07-21 19:36:36 +00:00
jmp m a i n
2022-05-27 15:52:45 +00:00
2022-04-03 12:13:47 +00:00
datapacket :
getmsg :
2022-09-18 12:02:18 +00:00
;inc $d2 ; Debug
2022-07-21 19:36:36 +00:00
;lda $90
2022-05-27 15:52:45 +00:00
;cmp #1
2022-07-21 19:36:36 +00:00
;bne nextpacket ; Data package with ID > 1
2022-04-03 12:13:47 +00:00
nextpacket :
ldx #2
fetchpacket :
2022-05-27 15:52:45 +00:00
2022-09-18 12:02:18 +00:00
lda M S G B U F ,x
2022-04-03 12:13:47 +00:00
ldy #0
sta ( S V P ) ,y
inc S V P
bne n n h b
2022-05-27 15:52:45 +00:00
inc S V P H
2022-04-03 12:13:47 +00:00
nnhb :
dec S L B
bne m o v e a l o n g
dec S H B
beq t x d o n e ; 0 bytes left - All done!
movealong :
dec S H B
lda S H B
jsr p r i n t b y t e
inc S H B
lda S L B
jsr p r i n t b y t e
jsr P R I M M
2022-05-27 15:52:45 +00:00
.asciiz " bytes l e f t ( h e x ) "
2022-04-03 12:13:47 +00:00
lda C R S R P N T
and #% 11000000 ; keep only section bits
ora #L I N E S T A R T ;
sta C R S R P N T
inx
cpx #32
bne f e t c h p a c k e t
jmp m a i n
txdone :
2022-09-18 12:02:18 +00:00
lda #U S E R L A N D H
sta U S E R L A N D P H
2022-04-03 12:13:47 +00:00
lda #0
2022-07-21 19:36:36 +00:00
sta S L B
sta S H B
sta S V P H ; Reset
2022-04-03 12:13:47 +00:00
sta k b _ r p t r ; Reset the keyboard pointers here.
sta k b _ w p t r
2022-09-18 12:02:18 +00:00
sta U S E R L A N D P
jsr P R I M M
.asciiz " \ nData l o a d e d i n t o R A M a t $ "
LDA #U S E R L A N D H
jsr p r i n t b y t e
;lda #USERLAND
;jsr printbyte
2022-04-03 12:13:47 +00:00
jsr P R I M M
2022-09-18 12:02:18 +00:00
.asciiz " 0 0 . \ nPress F 5 o r t y p e \ " r u n \ " t o s t a r t e x e c u t i n g . \ n "
2021-10-21 07:59:53 +00:00
nomsg :
2022-09-18 12:02:18 +00:00
jsr c h e c k c u r s o r
2022-04-03 12:13:47 +00:00
2022-09-18 12:02:18 +00:00
.ifdef DEBUG
2022-07-21 19:36:36 +00:00
lda k b _ f l a g s
and #D B G F L A G
beq n o d e b u g
2022-04-03 12:13:47 +00:00
lda C R S R P N T ; Save cursor..
2022-09-18 12:02:18 +00:00
sta S V C S R
2021-10-21 07:59:53 +00:00
pha
lda C R S R P N T 2
2022-09-18 12:02:18 +00:00
sta S V C S R + 1
2021-10-21 07:59:53 +00:00
pha
2022-04-03 12:13:47 +00:00
2022-09-18 12:02:18 +00:00
LDA #$ 65 ; Print debug in top right corner of screen
2022-04-03 12:13:47 +00:00
sta C R S R P N T
2022-09-18 12:02:18 +00:00
lda #$ 08
2022-04-03 12:13:47 +00:00
sta C R S R P N T 2
2022-05-27 15:52:45 +00:00
;lda #$6f
;sta CRSRPNT
lda ( D E B U G P ) ,y
jsr p r i n t b y t e
inc C R S R P N T ; Space
;LDA #$72 ; Debug ERRS and show cursor pointer next to timer on screen
;sta CRSRPNT
;lda #$27
;sta CRSRPNT2
2022-04-03 12:13:47 +00:00
lda E R R S
jsr p r i n t b y t e
2022-05-27 15:52:45 +00:00
inc C R S R P N T ; Space
2022-09-18 12:02:18 +00:00
lda S V C S R + 1
2022-04-03 12:13:47 +00:00
jsr p r i n t b y t e
2022-09-18 12:02:18 +00:00
lda S V C S R
2022-04-03 12:13:47 +00:00
jsr p r i n t b y t e
2022-05-27 15:52:45 +00:00
inc C R S R P N T ; Space
lda M I L L I S H
jsr p r i n t b y t e
inc C R S R P N T ; Space
lda I E R
jsr p r i n t b y t e
inc C R S R P N T ; Space
lda I F R
jsr p r i n t b y t e
inc C R S R P N T ; Space
2022-09-18 12:02:18 +00:00
;lda kbshift
;jsr printbyte
;inc CRSRPNT ; Space
2022-04-03 12:13:47 +00:00
2021-10-21 07:59:53 +00:00
pla
sta C R S R P N T 2
pla
sta C R S R P N T
2022-07-21 19:36:36 +00:00
nodebug :
2022-04-03 12:13:47 +00:00
.endif
2022-05-27 15:52:45 +00:00
2022-07-21 19:36:36 +00:00
jsr c h e c k k e y b o a r d
2022-05-27 15:52:45 +00:00
bne k e y _ p r e s s e d
2021-10-21 07:59:53 +00:00
jmp m a i n
2022-07-21 19:36:36 +00:00
checkkeyboard : ; Returns Z flag if nothing ready, not Z if something, kb_rptr in x
2022-09-18 12:02:18 +00:00
;sei ; Instead of disabling IRQ we might want to use the re-compare method.
2022-07-21 19:36:36 +00:00
;Load to x, then do the compare, then check if changed. Redo if changed. Idea for later..
2022-09-18 12:02:18 +00:00
lda #0
ldx s c r p
cpx s c w p
beq n o n e w s c
rescan :
2022-07-21 19:36:36 +00:00
jsr k e y b o a r d _ h a n d l i n g
2022-09-18 12:02:18 +00:00
lda #0
ldx s c r p
cpx s c w p
bne r e s c a n
cpx #7 ; Top of buffer
bcc n o n e w s c
sta s c r p ; 0
sta s c w p ; 0
nonewsc :
2022-07-21 19:36:36 +00:00
ldx k b _ r p t r
cpx k b _ w p t r
2022-09-18 12:02:18 +00:00
;bne gotkey
;sta kb_rptr
;sta kb_wptr
gotkey :
2022-07-21 19:36:36 +00:00
rts
copyscreen :
ldy #0
copypages :
lda ( S V P ) ,y
sta ( S L B ) ,y
iny
bne c o p y p a g e s
inc S V P H
inc S H B
dex
bne c o p y s c r e e n
rts
printscreen :
lda #0
sta S V P
sta S L B
2022-09-18 12:02:18 +00:00
lda #S C R E E N S T A R T H
2022-07-21 19:36:36 +00:00
sta S V P H
lda #$ 38
sta S H B
ldx #8
jsr c o p y s c r e e n
lda #0
sta S V P
sta S L B
lda #$ 38
sta S V P H
lda #$ 40
sta S H B ; End pointer
jmp e o m
loadscreen :
lda #0
sta S V P
sta S L B
lda #$ 38
sta S V P H
2022-09-18 12:02:18 +00:00
lda #S C R E E N S T A R T H
2022-07-21 19:36:36 +00:00
sta S H B
ldx #8
jsr c o p y s c r e e n
lda #0
sta S V P
sta S L B
sta S H B
jmp e o m
2021-10-21 07:59:53 +00:00
key_pressed :
2022-07-21 19:36:36 +00:00
;ldx kb_rptr ; Should already be in x
2021-10-21 07:59:53 +00:00
lda k b _ b u f f e r , x
cmp #$ 0 a ; enter - go new line
beq e n t e r _ p r e s s e d
2022-09-18 12:02:18 +00:00
cmp #$ 0 d
beq e n t e r _ p r e s s e d
2021-10-21 07:59:53 +00:00
cmp #$ 1 b ; escape - clear display
beq e s c
cmp #$ 08
beq b a c k
cmp #$ F E ; S c a n c o d e $ 05
beq f1
cmp #$ F D
beq f2
cmp #$ F C
beq f3
cmp #$ F B
beq f4
cmp #$ F A
beq f5
cmp #$ F 9
beq f6
cmp #$ F 8
beq f7
cmp #$ F 7
beq f8
2022-07-21 19:36:36 +00:00
cmp #P R T S C _ K E Y
beq p r i n t s c r e e n
2022-04-03 12:13:47 +00:00
cmp #L _ A R R _ K E Y
beq g o l r u d a r r
cmp #R _ A R R _ K E Y
beq g o l r u d a r r
cmp #U P _ A R R _ K E Y
beq g o l r u d a r r
cmp #D N _ A R R _ K E Y
beq g o l r u d a r r
2022-07-21 19:36:36 +00:00
cmp #F 12 _ K E Y
beq f12
2021-10-21 07:59:53 +00:00
jsr p r i n t k
2022-04-03 12:13:47 +00:00
printedkey :
inc k b _ r p t r
2021-10-21 07:59:53 +00:00
jmp m a i n
2022-04-03 12:13:47 +00:00
golrudarr :
jmp l r u d a r r
2021-10-21 07:59:53 +00:00
back :
jmp b a c k s p a c e _ p r e s s e d
2022-07-21 19:36:36 +00:00
f12 :
jmp l o a d s c r e e n
2021-10-21 07:59:53 +00:00
f8 :
jmp f8 _ p r e s s e d
f7 :
jmp f7 _ p r e s s e d
f6 :
jmp f6 _ p r e s s e d
f5 :
jmp f5 _ p r e s s e d
f4 :
jmp f4 _ p r e s s e d
f3 :
jmp f3 _ p r e s s e d
f2 :
jmp f2 _ p r e s s e d
f1 :
jmp f1 _ p r e s s e d
esc :
jmp e s c _ p r e s s e d
enter_pressed :
2022-04-03 12:13:47 +00:00
lda C R S R C H R
sta ( C R S R P N T ) ,y
2021-10-21 07:59:53 +00:00
ldx #0
lda k b _ b u f f e r ,x
parsecmd :
cmp #' r '
beq r e a d
cmp #' w '
beq w r i t e
cmp #' H '
beq s t r a n g e g a m e
cmp #' h '
beq s t r a n g e g a m e
jmp e r r
2022-04-03 12:13:47 +00:00
read :
jmp j r e a d
2021-10-21 07:59:53 +00:00
strangegame :
2022-04-03 12:13:47 +00:00
jsr P R I M M
.asciiz " \ n" , " A S T R A N G E G A M E . T H E O N L Y W I N N I N G " , " \ n " , " M O V E I S N O T T O P L A Y . " , " \ n "
2021-10-21 07:59:53 +00:00
wrotegtnw :
2022-04-03 12:13:47 +00:00
jmp e o m
jerr :
jmp e r r
2021-10-21 07:59:53 +00:00
write :
ldy #$ F F
inx
lda k b _ b u f f e r ,x
cmp #' r '
2022-04-03 12:13:47 +00:00
bne j e r r
2021-10-21 07:59:53 +00:00
ldx #6
jsr a s c t o b y t e
sta M O N H ; Maybe we'll find a better place
inx
jsr a s c t o b y t e
sta M O N L
nextbyte :
inx
lda k b _ b u f f e r ,x
cmp #' '
beq n e x t b y t e
cmp ' . '
beq n e x t b y t e
cmp ' ,'
beq n e x t b y t e
cmp ' $ '
beq n e x t b y t e
cmp #$ 0 a
beq e x i t w r i t e
stbyte :
jsr a s c t o b y t e
iny
sta ( M O N L ) ,y
jmp n e x t b y t e
exitwrite :
2022-04-03 12:13:47 +00:00
; inc kb_rptr
; jmp newmon ; Previous behavior
jsr P R I M M
.asciiz " \ nWrote "
iny
tya
jsr p r i n t b y t e
jsr P R I M M
.asciiz " bytes. P r e s s F 1 t o e n t e r m o n i t o r \ n "
jmp e o m
2021-10-21 07:59:53 +00:00
2022-04-03 12:13:47 +00:00
jread :
2021-10-21 07:59:53 +00:00
inx
lda k b _ b u f f e r ,x
cmp #' u '
beq r u n
cmp #' e '
bne e r r
ldx #5
jsr a s c t o b y t e
sta M O N H
inx
jsr a s c t o b y t e
sta M O N L
2022-04-03 12:13:47 +00:00
; inc kb_rptr
; jmp newmon
2022-10-18 09:00:00 +00:00
jsr P R I M M
.asciiz " \ nRead : \ n"
reread :
lda C R S R P N T
and #% 11000000 ; keep only section bits
ora #L I N E S T A R T ;
sta C R S R P N T
2022-04-03 12:13:47 +00:00
ldy #0
2022-10-18 09:00:00 +00:00
sty k b _ r p t r
sty k b _ w p t r
2022-04-03 12:13:47 +00:00
lda ( M O N L ) ,y
jsr p r i n t b y t e
2022-10-18 09:00:00 +00:00
jsr c h e c k k e y b o a r d
beq r e r e a d
2022-04-03 12:13:47 +00:00
jsr P R I M M
.asciiz " \ nPress F 1 t o e n t e r m o n i t o r \ n "
2022-10-18 09:00:00 +00:00
2022-04-03 12:13:47 +00:00
jmp e o m
2021-10-21 07:59:53 +00:00
err :
lda C R S R P N T
jsr c r n l
sta C R S R P N T
bcc c l k b p t r
inc C R S R P N T 2
2022-04-03 12:13:47 +00:00
lda ( C R S R P N T ) ,y
sta C R S R C H R
2021-10-21 07:59:53 +00:00
clkbptr :
; Clear keyboard pointers if this is the end of message
inc k b _ r p t r
lda k b _ r p t r
cmp k b _ w p t r
bne n o t d o n e
eom :
2022-07-21 19:36:36 +00:00
; lda (CRSRPNT),y ; Save new char under cursor ; Here or in err:?
; sta CRSRCHR
2021-10-21 07:59:53 +00:00
lda #0
sta k b _ r p t r
sta k b _ w p t r
notdone :
jmp m a i n
run :
2022-09-18 12:02:18 +00:00
jmp ( U S E R L A N D P )
2021-10-21 07:59:53 +00:00
esc_pressed :
jsr c l r s c n
lda #S C R E E N S T A R T L
sta C R S R P N T
lda #S C R E E N S T A R T H
sta C R S R P N T 2
jmp c l k b p t r
backspace_pressed :
2022-09-18 12:02:18 +00:00
jsr r u b o u t
2021-10-21 07:59:53 +00:00
jmp m a i n
f1_pressed :
lda #0
sta k b _ r p t r
sta k b _ w p t r
jsr c l r s c n
jmp m o n m o n
f2_pressed :
2022-09-18 12:02:18 +00:00
lda #$ 10
sta S V P H
lda #$ 01
sta S H B
lda #0
sta S V P
sta S L B
inc S L B
2022-07-21 19:36:36 +00:00
jsr s a v e t o t a p e
2021-10-21 07:59:53 +00:00
jmp e o m
f3_pressed :
2022-10-18 09:00:00 +00:00
.ifdef BASIC
2022-09-18 12:02:18 +00:00
lda #> R A M S T A R T 2
sta S V P H
lda #< R A M S T A R T 2
sta S V P
2022-10-18 09:00:00 +00:00
.endif
2022-07-21 19:36:36 +00:00
jsr l o a d f r o m t a p e
2021-10-21 07:59:53 +00:00
jmp e o m
2022-04-03 12:13:47 +00:00
2022-10-18 09:00:00 +00:00
2021-10-21 07:59:53 +00:00
f4_pressed :
2022-09-18 12:02:18 +00:00
.ifdef BASIC
jsr c l r s c n
lda #0
sta k b _ r p t r
sta k b _ w p t r
lda #S C R E E N S T A R T H
sta C R S R P N T + 1
lda #S C R E E N S T A R T L
sta C R S R P N T
jmp C O L D _ S T A R T
.endif
2021-10-21 07:59:53 +00:00
jmp e o m
f5_pressed :
2022-07-21 19:36:36 +00:00
;jsr rf_nop
2022-04-03 12:13:47 +00:00
jmp r u n
2021-10-21 07:59:53 +00:00
f6_pressed :
2022-10-18 09:00:00 +00:00
;jsr readrf24regs
;jsr PRIMM
;.asciiz "Read RF24 configuration!"
;jsr newline
2022-04-03 12:13:47 +00:00
jmp e o m
2021-10-21 07:59:53 +00:00
f7_pressed :
2022-09-18 12:02:18 +00:00
jsr r e s e t k b
2022-04-03 12:13:47 +00:00
jmp e o m
2021-10-21 07:59:53 +00:00
f8_pressed :
2022-04-03 12:13:47 +00:00
jmp r e s e t
2021-10-21 07:59:53 +00:00
newmon :
jsr c l r s c n
monmon :
2022-04-03 12:13:47 +00:00
lda #29
2021-10-21 07:59:53 +00:00
sta M O N C N T
lda M O N H
pha
lda M O N L
pha
jsr m o n
pla
sta M O N L
pla
sta M O N H
2022-07-21 19:36:36 +00:00
jsr c h e c k k e y b o a r d
2021-10-21 07:59:53 +00:00
beq m o n m o n
2022-07-21 19:36:36 +00:00
parsekey :
lda k b _ b u f f e r ,x
2021-10-21 07:59:53 +00:00
inc k b _ r p t r
2022-04-03 12:13:47 +00:00
cmp #E S C _ K E Y ; e s c a p e - e x i t
2021-10-21 07:59:53 +00:00
beq e x i t m o n
2022-04-03 12:13:47 +00:00
cmp #P G U P _ K E Y
beq m o n p g u p
cmp #P G D N _ K E Y
beq m o n p g d n
cmp #U P _ A R R _ K E Y
beq m o n u p
cmp #D N _ A R R _ K E Y
beq m o n d n
2021-10-21 07:59:53 +00:00
2022-07-21 19:36:36 +00:00
jsr c h e c k k e y b o a r d
bne p a r s e k e y
2021-10-21 07:59:53 +00:00
; Let's loop here until keypress
jmp m o n m o n ; No data - restart monitor
2022-04-03 12:13:47 +00:00
mondn : ; Arrow keys invert the natural direction because pressing down naturally means you want to see another line
clc
lda M O N L
adc #$ 08
sta M O N L
bcc m o n m o n
inc M O N H
jmp m o n m o n
monup : ; Pressing up means you want to see a line higher up == lower
sec
lda M O N L
sbc #$ 08
sta M O N L
bcs m o n m o n
dec M O N H
jmp m o n m o n
monpgdn :
clc
lda M O N L
adc #$ D 8
sta M O N L
bcc m o n m o n
inc M O N H
jmp m o n m o n
monpgup :
sec
lda M O N L
sbc #$ D 8
sta M O N L
bcs m o n m o n
dec M O N H
jmp m o n m o n
2021-10-21 07:59:53 +00:00
exitmon :
jsr c l r s c n ; Clear screen on monitor exit
2022-04-03 12:13:47 +00:00
lda #S C R E E N S T A R T L
sta C R S R P N T
lda #S C R E E N S T A R T H
sta C R S R P N T 2
2021-10-21 07:59:53 +00:00
jmp e o m
; lda #0
; sta MILLISH
asctohex :
cmp #$ 60
bcc c a p s
2022-04-03 12:13:47 +00:00
sbc #$ 21
2021-10-21 07:59:53 +00:00
caps :
sbc #' 0 ' - 1
cmp #10
bcc n o t h e x
2022-04-03 12:13:47 +00:00
sbc #7
2021-10-21 07:59:53 +00:00
nothex :
rts
2022-09-18 12:02:18 +00:00
checkcursor :
bit M I L L I S
bmi i s n e g
lda k b _ f l a g s
and #$ 7 f
sta k b _ f l a g s ; Reset flip
bne s k i p p e d c u r s o r ; BRA
isneg :
bit k b _ f l a g s ; Same as last?
bpl f l i p
bmi s k i p p e d c u r s o r ; We already flipped
flip :
ldy #0
lda k b _ f l a g s
eor #C R S R
ora #C R S R F ; S e t f l i p b i t
sta k b _ f l a g s
bit k b _ f l a g s
bvs c u r s o r o f f
cursoron :
lda #' _ '
sta ( C R S R P N T ) ,y
bne c u r s o r d o n e ; BRA
cursoroff :
lda C R S R C H R
sta ( C R S R P N T ) ,y
cursordone :
skippedcursor :
rts
MONRDKEY :
sty T M P 4
stx T M P 3 ; X to TMP3
chkkb :
jsr c h e c k c u r s o r
jsr c h e c k k e y b o a r d
beq c h k k b ; We can either block here or return $06 = ACK
lda k b _ b u f f e r , x
inc k b _ r p t r
; cmp #$08
; bne notback
; lda #$5F ; OSI basic thinks _ is rubout. Fall through.
; notback:
cmp #$ 0 A
bne n o n e w l i n e
lda #$ 0 D ; NL to CR
nonewline :
ldy T M P 4
ldx T M P 3
rts
2022-10-18 09:00:00 +00:00
.ifdef BASIC
2022-09-18 12:02:18 +00:00
MONISCNTC :
sty T M P 4
stx T M P 3 ; X to TMP3
jsr c h e c k k e y b o a r d
beq N O T C N T C
lda k b _ b u f f e r , x
inc k b _ r p t r
cmp #' ^ '
bne N O T C N T C
lda k b _ f l a g s
and #E C O D E
beq N O T C N T C ; If strangely not actually holding CTRL or other extended key
ldy T M P 4
ldx T M P 3
sec
;jmp STOP
jmp C O N T R O L _ C _ T Y P E D
NOTCNTC :
ldy T M P 4
ldx T M P 3
clc
rts
bell :
lda #$ 02
sta C T R L
jsr s i m p l e d e l a y
lda #1
sta C T R L
bne d o n e r u b o u t
MONCOUT :
cmp #0
beq s k i p c o u t
sty T M P 4
stx T M P 3 ; X to TMP3
pha
lda k b _ f l a g s
ora #C R S R F ; S e t f l i p b i t
sta k b _ f l a g s
ldy #0
lda #0
sta ( C R S R P N T ) ,y
pla
cmp #7
beq b e l l
cmp #$ 0 D
bne n o t c r
jmp d o n e r u b o u t
notcr :
cmp #$ 08
bne n o t r u b o u t
lda #' '
sta ( C R S R P N T ) ,y
jsr n o r m c r s r ; Backspace
dec k b _ r p t r
jmp d o n e r u b o u t
notrubout :
jsr p r i n t k
donerubout :
ldy T M P 4
ldx T M P 3
skipcout :
rts
2022-10-18 09:00:00 +00:00
.endif
2022-09-18 12:02:18 +00:00
2021-10-21 07:59:53 +00:00
clrscn :
lda #0
sta C R S R P N T
2022-09-18 12:02:18 +00:00
lda #S C R E E N S T A R T H ; C l e a r b e f o r e s c r e e n t o a f t e r s c r e e n
2022-04-03 12:13:47 +00:00
sta C R S R P N T 2
2021-10-21 07:59:53 +00:00
ldy #0
tya
2022-09-18 12:02:18 +00:00
ldx #8
2021-10-21 07:59:53 +00:00
clrloop :
sta ( C R S R P N T ) ,y
iny
bne c l r l o o p
2022-04-03 12:13:47 +00:00
inc C R S R P N T 2 ; increasing HI-byte of the clearing address.
2021-10-21 07:59:53 +00:00
dex
bne c l r l o o p
rts
crnl : ; Carriage return new line - needs cursor pointer in A
and #% 11000000 ; keep only section bits
ora #L I N E S T A R T ;
clc
adc #$ 40 ; CR
rts
2022-04-03 12:13:47 +00:00
newline :
lda C R S R P N T
jsr c r n l
sta C R S R P N T
and #$ E 0 ; If msn is 0 then ++section
bne n e w l i n e d o n e
inc C R S R P N T 2
newlinedone :
2022-09-18 12:02:18 +00:00
jsr c h e c k b o t t o m
2022-04-03 12:13:47 +00:00
rts
2021-10-21 07:59:53 +00:00
hextoa :
; wozmon-style
; and #%00001111 ; Mask LSD for hex print.
; Already masked when we get here.
ora #' 0 ' ; Add '0'.
cmp #' 9 ' + 1 ; Is it a decimal digit?
bcc a s c r ; Yes, output it.
adc #$ 06 ; Add offset for letter.
ascr :
rts
bytetoa : ;This SR puts LSB in A and MSB in HXH - as ascii using hextoa.
pha
lsr
lsr
lsr
lsr
clc
jsr h e x t o a
sta H X H
pla
and #$ 0 F
jsr h e x t o a
rts
asctobyte : ; Reads two hex characters from keyboard buffer, x indexed, and returns a byte in A
lda k b _ b u f f e r ,x ; MSD
jsr a s c t o h e x
asl a
asl a
asl a
asl a
sta T M P
inx
lda k b _ b u f f e r ,x ; LSD
jsr a s c t o h e x
ora T M P
; Return value in A
rts
mon :
; Print line starting address
; Print 8 ascii hex bytes separated by ' '
; Print same 8 bytes as ASCII
;newline
;Let's start by resetting start pos
lda #S C R E E N S T A R T H ; I f w e a r e , t h e n r e s e t t o t o p o f s c r e e n
sta C R S R P N T 2
lda #S C R E E N S T A R T L
sta C R S R P N T
nextline :
2022-09-18 12:02:18 +00:00
jsr c h e c k k e y b o a r d
beq n o k b
rts
nokb :
2021-10-21 07:59:53 +00:00
ldx #8
lda #' $ '
jsr p r i n t a
lda M O N H
jsr p r i n t b y t e
lda M O N L
jsr p r i n t b y t e
lda #' : '
jsr p r i n t a
lda #' '
jsr p r i n t a
ldy #0
nexthex :
lda ( M O N L ) ,y
sta A B U F ,x
jsr p r i n t b y t e
inc C R S R P N T ; Make a space
inc M O N L
bne n o t o f
inc M O N H
notof :
dex
bne n e x t h e x
; Print ascii
ldx #8
printabuf :
lda A B U F ,x
2022-05-27 15:52:45 +00:00
cmp #$ 0 A
bne n o t n l
tya ; Zero A
notnl :
2021-10-21 07:59:53 +00:00
jsr p r i n t a
dex
bne p r i n t a b u f
; Get ready for a new line
lda C R S R P N T
jsr c r n l ; Carriage Return New Line
sta C R S R P N T
and #$ E 0 ; If msn is 0 then ++section
bne g o n e x t
inc C R S R P N T 2
gonext :
dec M O N C N T
bne n e x t l i n e ; Was this the last line? No, nextline.
rts
printbyte :
2022-07-21 19:36:36 +00:00
pha ; Save A
2021-10-21 07:59:53 +00:00
jsr b y t e t o a
pha
lda H X H
jsr p r i n t a
pla
jsr p r i n t a
2022-07-21 19:36:36 +00:00
pla ; Restore A
2021-10-21 07:59:53 +00:00
rts
2022-05-27 15:52:45 +00:00
printfast :
sta ( C R S R P N T ) ,y
inc C R S R P N T
bne p r i n t e d f a s t
inc C R S R P N T 2
printedfast :
rts
2022-09-18 12:02:18 +00:00
printpos :
ldy #0
tax
lda C R S R P N T
sta S L B ; Not doing this while using
lda C R S R P N T 2
sta S H B
lda #08
sta C R S R P N T 2
lda #$ 4 f
sta C R S R P N T
lda #' A '
jsr p r i n t f a s t
txa
jsr p r i n t b y t e
inc C R S R P N T
lda S H B
jsr p r i n t b y t e
lda S L B
jsr p r i n t b y t e
inc C R S R P N T
lda #' Y '
jsr p r i n t f a s t
lda T M P 4
jsr p r i n t b y t e
inc C R S R P N T
lda #' X '
jsr p r i n t f a s t
lda T M P 3
jsr p r i n t b y t e
inc C R S R P N T
ldy S H B
sty C R S R P N T 2
ldy S L B
sty C R S R P N T
txa
rts
2021-10-21 07:59:53 +00:00
printa :
2022-04-03 12:13:47 +00:00
sta T M P 2 ; save A
TYA ; copy Y
PHA ; save Y
TXA ; copy X
PHA ; save X
2021-10-21 07:59:53 +00:00
ldy #0
2022-04-03 12:13:47 +00:00
lda T M P 2
cmp #$ 0 A ; Do we need this?
beq p r i n t n e w l i n e
2021-10-21 07:59:53 +00:00
sta ( C R S R P N T ) ,y
inc C R S R P N T
bne p r i n t e d a
inc C R S R P N T 2
printeda :
2022-04-03 12:13:47 +00:00
PLA ; pull value
TAX ; restore X
PLA ; pull value
TAY ; restore Y
2022-09-18 12:02:18 +00:00
lda T M P 2 ; Keep key in A
2021-10-21 07:59:53 +00:00
rts
2022-04-03 12:13:47 +00:00
printnewline :
jsr n e w l i n e
jmp p r i n t e d a
lrudarr :
; bit MILLIS
; bpl correctchr Not worth testing...
pha
ldy #0
lda C R S R C H R ; Make sure we leave the character in the position and not the cursor.
sta ( C R S R P N T ) ,y
correctchr :
pla
cmp #R _ A R R _ K E Y
beq r a r r
cmp #U P _ A R R _ K E Y
beq u p a r r
cmp #D N _ A R R _ K E Y
beq d n a r r
larr :
dec C R S R P N T ; Move cursor left
lda C R S R P N T
cmp #255
bne c h e c k l i n e
dec C R S R P N T 2
checkline :
and #% 00111111
cmp #L I N E S T A R T
bcs c h e c k e d a r r o w s
lda C R S R P N T
sec
2022-09-18 12:02:18 +00:00
sbc #$ 41
ora #$ 3 e
2022-04-03 12:13:47 +00:00
sta C R S R P N T
bcs c h e c k e d a r r o w s
dec C R S R P N T 2
bcc c h e c k e d a r r o w s ; BRA
rarr :
inc C R S R P N T
lda C R S R P N T
and #$ 3 F ; Discard MS bits since we only care about current line
2022-09-18 12:02:18 +00:00
cmp #L I N E E N D + 1
2022-04-03 12:13:47 +00:00
bcc c h e c k e d a r r o w s ; A < 62 == Not Front porch
jsr n e w l i n e
ora #L I N E S T A R T
sta C R S R P N T
jmp c h e c k e d a r r o w s
uparr :
lda C R S R P N T
sec
sbc #$ 40
sta C R S R P N T
bcs c h e c k e d a r r o w s
dec C R S R P N T 2
bcc c h e c k e d a r r o w s ; BRA
dnarr :
lda C R S R P N T
clc
adc #$ 40
sta C R S R P N T
bcc c h e c k e d a r r o w s
inc C R S R P N T 2
jmp c h e c k e d a r r o w s
checkedarrows :
jsr c h e c k b o t t o m
lda ( C R S R P N T ) ,y ; Save new char under cursor
sta C R S R C H R
lda k b _ f l a g s
ora #C R S R
sta k b _ f l a g s
lda #' _ '
sta ( C R S R P N T ) ,y
jmp p r i n t e d k e y
2021-10-21 07:59:53 +00:00
printk :
pha
checkl : ; This is user input, so we have to make sure we don't hit VGA blanking by mistake
lda C R S R P N T
and #$ 3 F ; Discard MS bits since we only care about current line
2022-05-27 15:52:45 +00:00
cmp #L I N E E N D
2021-10-21 07:59:53 +00:00
bcc c h s ; A < 62 == Not Front porch
2022-04-03 12:13:47 +00:00
jsr n e w l i n e
2021-10-21 07:59:53 +00:00
chs :
2022-04-03 12:13:47 +00:00
cmp #L I N E S T A R T
bcs c h s2
ora C R S R P N T
2021-10-21 07:59:53 +00:00
sta C R S R P N T
2022-04-03 12:13:47 +00:00
chs2 :
jsr c h e c k b o t t o m
2021-10-21 07:59:53 +00:00
rpa :
pla
jsr p r i n t a
rts
2022-04-03 12:13:47 +00:00
checkbottom :
2022-09-18 12:02:18 +00:00
tya
pha
2022-04-03 12:13:47 +00:00
lda C R S R P N T 2 ; Check if we're off screen
2022-09-18 12:02:18 +00:00
cmp #S C R E E N S T A R T H
2022-04-03 12:13:47 +00:00
bcc r e s e t c u r s o r ; Off screen
2022-09-18 12:02:18 +00:00
cmp #$ 07 + S C R E E N S T A R T H
2022-04-03 12:13:47 +00:00
bcc c h e c k e d b o t t o m ; if we're not
lda C R S R P N T ; Check LSB as well if we're above $2700
cmp #$ 80
bcc c h e c k e d b o t t o m
resetcursor :
2022-09-18 12:02:18 +00:00
jsr s c r o l l s l o w
lda #S C R E E N S T A R T H + 7 ; If we are, then reset to bottom of screen
2022-04-03 12:13:47 +00:00
sta C R S R P N T 2
lda #S C R E E N S T A R T L
sta C R S R P N T
checkedbottom :
2022-09-18 12:02:18 +00:00
pla
tay
rts
scrolldown :
lda #S C R E E N S T A R T H + 1
sta S C R L P N T 2 + 1
sta S C R L P N T + 1
dec S C R L P N T + 1
lda #0
sta S C R L P N T
sta S C R L P N T 2
nextblock :
ldy #$ F F
moveblock :
lda ( S C R L P N T 2 ) ,y
sta ( S C R L P N T ) ,y
dey
bne m o v e b l o c k
inc S C R L P N T + 1
inc S C R L P N T 2 + 1
lda S C R L P N T 2 + 1
cmp #S C R E E N S T A R T H + 8
bne n e x t b l o c k
lda #0
clearlast :
sta ( S C R L P N T ) ,y
dey
bne c l e a r l a s t
sta ( S C R L P N T ) ,y ; Clear y = 0 too
rts
scrollslow :
clc
ldy #0
lda #S C R E E N S T A R T H
sta S C R L P N T 2 + 1
sta S C R L P N T + 1
lda #S C R E E N S T A R T L
sta S C R L P N T
adc #$ 40 ; Line down
sta S C R L P N T 2
bcc m o v e l i n e
inc S C R L P N T 2 + 1
moveline :
lda ( S C R L P N T 2 ) ,y
sta ( S C R L P N T ) ,y
;lda #0
;sta (SCRLPNT2),y ; Lazy code - actually only need to do this for last line
iny
cpy #$ 40
bne m o v e l i n e
clc
lda S C R L P N T 2
sta S C R L P N T
adc #$ 40
sta S C R L P N T 2
lda S C R L P N T 2 + 1
sta S C R L P N T + 1
ldy #0
bcc l 1 3 7 5
inc S C R L P N T 2 + 1
l1375 :
lda S C R L P N T 2 + 1
cmp #S C R E E N S T A R T H + 7
bne m o v e l i n e
lda S C R L P N T 2
cmp #$ 7 F
bcc m o v e l i n e
ldy #$ 40
lda #0
clearlastline :
sta ( S C R L P N T ) ,y
dey
bne c l e a r l a s t l i n e
rts
resetkb :
sei
lda #$ 11
sta C T R L
LDA #% 01000000
STA A C R ; T1 continuous - disable Shift register
lda #% 00100100
sta I E R ; Disable T2 + SR
;jsr delay20ms
jsr s i m p l e d e l a y ; Should be checked and optimized... Hmm...
jsr s i m p l e d e l a y
jsr s i m p l e d e l a y
jsr s i m p l e d e l a y
jsr s i m p l e d e l a y
jsr s i m p l e d e l a y
jsr s i m p l e d e l a y
jsr s i m p l e d e l a y
jsr s i m p l e d e l a y
LDA #% 01101100
STA A C R ; T1 continuous, T2 count, PB7 disabled, Shift In External
lda #5
sta T 2 C L
lda #% 11100100 ; Set T1 + T2 + SR
sta I E R
lda #0
sta S R 1
sta s c w p
sta s c r p
sta k b _ w p t r
sta k b _ r p t r
sta t 2 i r q r e g 1
2022-10-18 09:00:00 +00:00
sta k b _ f l a g s
2022-09-18 12:02:18 +00:00
sta T 2 C H
lda #1
sta C T R L
bit T 1 C L ; Clear irq
cli
2022-04-03 12:13:47 +00:00
rts
2021-10-21 07:59:53 +00:00
2022-07-21 19:36:36 +00:00
; IRQ code starts here - enters at irq:
badpacket :
2022-09-18 12:02:18 +00:00
jsr r e s e t k b
2022-07-21 19:36:36 +00:00
beq e x i t i r q ; BRA
t2_irq :
;Time critical stuff
ldx S R 1
2022-09-18 12:02:18 +00:00
lda t 2 i r q r e g 1 ; If 0 this is first packet, not second
2022-07-21 19:36:36 +00:00
bne s e c o n d
2022-09-18 12:02:18 +00:00
lda #4 ; 5 bits
2022-07-21 19:36:36 +00:00
sta T 2 C L
lda #0
sta T 2 C H
2022-09-18 12:02:18 +00:00
stx t 2 i r q r e g 2
inc t 2 i r q r e g 1
2022-07-21 19:36:36 +00:00
bne e x i t i r q ; BRA
second :
2022-09-18 12:02:18 +00:00
lda #5 ; 6 bits
2022-07-21 19:36:36 +00:00
sta T 2 C L
lda #0
sta T 2 C H
sta S R 1
2022-09-18 12:02:18 +00:00
sta t 2 i r q r e g 1
2022-07-21 19:36:36 +00:00
txa
lsr
2022-09-18 12:02:18 +00:00
bcc b a d p a c k e t ; Stop bit should be 1 - not checking parity.. yet
2022-07-21 19:36:36 +00:00
lsr
and #$ 0 F
2022-09-18 12:02:18 +00:00
asl t 2 i r q r e g 2
asl t 2 i r q r e g 2
asl t 2 i r q r e g 2
bcs b a d p a c k e t ; Start bit should be 0 in C - if not we're in trouble anyway
ora t 2 i r q r e g 2
2022-07-21 19:36:36 +00:00
ldx s c w p ; Scan code write pointer
sta s c b u f , x ; Store to scan code buffer
inc s c w p
exitirq :
pla
2022-09-18 12:02:18 +00:00
tay ; Restore x and y
pla
2022-07-21 19:36:36 +00:00
tax
pla
rti
exitsrirq :
bit S R 1 ; Clear SR IRQ
pla
rti
2022-09-18 12:02:18 +00:00
ca1_irq :
jmp c a1 i r q
2022-07-21 19:36:36 +00:00
hitbrk :
2022-09-18 12:02:18 +00:00
; jmp reset
inc b r k c n t
lda $ 1 0 4 ,x
sta $ 6 0 0
2022-07-21 19:36:36 +00:00
lda #< m a i n
sta $ 1 0 4 ,x ; Return to main instead of breakpoint
2022-09-18 12:02:18 +00:00
lda $ 1 0 5 ,x
sta $ 6 0 1
2022-07-21 19:36:36 +00:00
lda #> m a i n
sta $ 1 0 5 ,x
jmp e x i t i r q
2021-10-21 07:59:53 +00:00
; IRQ vector points here ; Thanks to Ben Eater for a very useful PS2->Ascii interface
2022-04-03 12:13:47 +00:00
;IFR is IRQ Tl T2 CBl CB2 SR CA1 CA2
2021-10-21 07:59:53 +00:00
irq :
2022-05-27 15:52:45 +00:00
pha ; Save A
2022-07-21 19:36:36 +00:00
lda I F R
and #4
bne e x i t s r i r q
2022-05-27 15:52:45 +00:00
txa
pha ; Save X
2022-09-18 12:02:18 +00:00
tya
pha ; Save y
2022-05-27 15:52:45 +00:00
2022-07-21 19:36:36 +00:00
lda #% 00100000 ; We need T2 to fire super fast, so we check it first.;
and I F R
bne t 2 _ i r q
lda I E R ; Priority to ca1 but only if enabled
and I F R
tax
and #2 ; CA1
2022-09-18 12:02:18 +00:00
bne c a1 _ i r q ; Disabled so it doesn't mess up things...
2022-07-21 19:36:36 +00:00
2022-04-03 12:13:47 +00:00
;Alt approach
2022-07-21 19:36:36 +00:00
;lda IER
;and IFR ; We only care about active IRQ's
txa ; IER AND IFR
2022-05-27 15:52:45 +00:00
asl ; IRQ in C
asl ; T1 flag in C
bcs t 1 _ i r q
2022-07-21 19:36:36 +00:00
; asl ; T2
;bcs t2_irq
; asl ; CB1
2022-05-27 15:52:45 +00:00
;asl ; CB2
2022-07-21 19:36:36 +00:00
; asl ; SR
;asl ; CA1
; bcs ca1_irq
2022-04-03 12:13:47 +00:00
; bcs keyboard_interrupt
; asl ; CA2
2022-05-27 15:52:45 +00:00
; bit IFR ; T1 as fast as possible
; bvs t1_irq
2022-04-03 12:13:47 +00:00
2021-10-21 07:59:53 +00:00
tsx
2022-09-18 12:02:18 +00:00
inx
2021-10-21 07:59:53 +00:00
lda $ 0 1 0 3 ,x ; Pull status register off stack and check break flag
and #$ 10
bne h i t b r k
2022-04-03 12:13:47 +00:00
2022-05-27 15:52:45 +00:00
; lda IFR
; and #2
; bne keyboard_interrupt
2022-04-03 12:13:47 +00:00
inc E R R S ;Should never end up here...
2022-07-21 19:36:36 +00:00
jmp e x i t i r q
2021-10-21 07:59:53 +00:00
2022-10-18 09:00:00 +00:00
gogmillis :
jmp g m i l l i s
2022-04-03 12:13:47 +00:00
t1_irq :
bit T 1 C L ; Clear irq
2022-07-21 19:36:36 +00:00
bit A C R ; Are we saving to tape?
bpl g m i l l i s ; No - just increment millis
dec P U L S E S
bne g m i l l i s
;lda #2
;sta PULSES ; Let's set pulses to KCS individually pr bit
; Here we need to keep track of the current byte and current bit - 16 IRQ(half pulses) pr bit
; SVP Save pointer low
; CBIT current bit mask
2022-10-18 09:00:00 +00:00
; Probably don't need this flag anymore
;lda TAPEFLAGS ; If we just started then send a 0 bit to make the 7F leader
;bpl running
;and #$7F ; Remove flag
;sta TAPEFLAGS
;inc BITNO
;lda PULSESL ; 8 Half pulses of 1200Hz
;asl ; PULSESL holds full cycles
;sta PULSES
;lda #3
;sta T1LH
;lda #$3f
;sta T1LL
;bne t1_irq_exit ; BRA
2022-07-21 19:36:36 +00:00
running :
2022-10-18 09:00:00 +00:00
inc B I T N O
lda B I T N O
cmp #13 ; This is a bit messy, could use a fix
bne n o t n e w b y t e
lda #1
sta B I T N O
jmp s e n d0
notnewbyte :
cmp #1
beq s e n d0
cmp #10 ; Bit 10 and 11 should send a 1
bcs s e n d1
2022-07-21 19:36:36 +00:00
lda C B I T
bne h e r e ; Mask bit has not been shifted out yet
lda #1 ; Mask = LSB
sta C B I T
here : ; New bit
2022-09-18 12:02:18 +00:00
ldy #0
2022-07-21 19:36:36 +00:00
and ( S V P ) ,y ; Assuming y is 0
beq s e n d0 ; Bit was 0
send1 :
lda P U L S E S H ; 16 Half pulses of 2400Hz
asl ; PULSESH holds whole cycles
sta P U L S E S
lda #1
sta T 1 L H
lda #$ 9 f
2022-10-18 09:00:00 +00:00
bne t h e r e ; BRA
2022-07-21 19:36:36 +00:00
send0 :
lda P U L S E S L ; 8 Half pulses of 1200Hz
asl ; PULSESL holds full cycles
sta P U L S E S
lda #3
sta T 1 L H
lda #$ 3 f
there :
sta T 1 L L
2022-10-18 09:00:00 +00:00
lda B I T N O
cmp #1
beq n o t d o n e y e t
cmp #12
beq g o n e x t b i t ; This little bit of juggling means we move on to the next byte after the stop bits
cmp #9
bcs n o t d o n e y e t
gonextbit :
2022-07-21 19:36:36 +00:00
clc ; Let's make sure we don't shift in a carry by mistake
asl C B I T ;Next bit
bne n o t d o n e y e t
inc S V P ; Increment pointer = New byte
2022-09-18 12:02:18 +00:00
bne a r e w e d o n e
2022-07-21 19:36:36 +00:00
inc S V P H ; High byte
2022-09-18 12:02:18 +00:00
;lda SVPH
;cmp SHB ; Maybe not the right variable to use?
;bcc notdoneyet
arewedone :
dec S L B
bne n o t d o n e y e t
dec S H B
bne n o t d o n e y e t
2022-07-21 19:36:36 +00:00
lda A C R
and #$ 7 f
sta A C R
bne t 1 _ i r q _ e x i t ; BRAnch always
notdoneyet :
2022-04-03 12:13:47 +00:00
gmillis :
2022-09-18 12:02:18 +00:00
2022-04-03 12:13:47 +00:00
inc M I L L I S
bne t 1 _ i r q _ e x i t
inc M I L L I S + 1
2022-09-18 12:02:18 +00:00
dec L O A D T I M E O U T
2022-04-03 12:13:47 +00:00
t1_irq_exit :
2022-07-21 19:36:36 +00:00
jmp e x i t i r q
2022-04-03 12:13:47 +00:00
2022-05-27 15:52:45 +00:00
; cb1_IRQ:
; dec kbbit
; lda PORTB ; clear IRQ
; pla
; rti
2022-04-03 12:13:47 +00:00
2022-07-21 19:36:36 +00:00
keyboard_handling : ; SR, not IRQ any longer
lda s c b u f , x
2022-09-18 12:02:18 +00:00
inc s c r p
2022-05-27 15:52:45 +00:00
tax
lda r e v e r s e b i t s , x
2022-07-21 19:36:36 +00:00
tax
2022-05-27 15:52:45 +00:00
; Fall through to scancode -> ascii parsing -> key buffer
keyboard_interrupt :
lda k b _ f l a g s
and #R E L E A S E ; c h e c k i f w e ' r e r e l e a s i n g a k e y
beq r e a d _ k e y ; otherwise, read the key
lda k b _ f l a g s
eor #R E L E A S E ; f l i p t h e r e l e a s i n g b i t
sta k b _ f l a g s
; lda PORTA ; read key value that's being released
2022-07-21 19:36:36 +00:00
; lda KEYBOARD
txa
2022-05-27 15:52:45 +00:00
cmp #$ 12 ; left shift
beq s h i f t _ u p
cmp #$ 59 ; right shift
beq s h i f t _ u p
2022-09-18 12:02:18 +00:00
cmp #$ 14
beq e k e y _ u p
bne e x i t
2022-05-27 15:52:45 +00:00
2022-09-18 12:02:18 +00:00
ekey_up :
lda k b _ f l a g s
and #% 11111011 ; Turn off ecode
sta k b _ f l a g s
jmp e x i t
2022-04-03 12:13:47 +00:00
2021-10-21 07:59:53 +00:00
shift_up :
lda k b _ f l a g s
eor #S H I F T ; f l i p t h e s h i f t b i t
sta k b _ f l a g s
jmp e x i t
2022-04-03 12:13:47 +00:00
break :
jmp n o c l e a r
2021-10-21 07:59:53 +00:00
read_key :
2022-07-21 19:36:36 +00:00
txa
2022-04-03 12:13:47 +00:00
cmp #$ 77 ; Either numlock or pause/break - we reset without clearing ram
beq b r e a k
2021-10-21 07:59:53 +00:00
cmp #$ f 0 ; if releasing a key
beq k e y _ r e l e a s e ; set the releasing bit
cmp #$ 12 ; left shift
beq s h i f t _ d o w n
cmp #$ 59 ; right shift
beq s h i f t _ d o w n
2022-04-03 12:13:47 +00:00
cmp #$ E 0
beq e k e y _ d o w n
2022-09-18 12:02:18 +00:00
cmp #$ 14
beq e k e y _ d o w n
2021-10-21 07:59:53 +00:00
lda k b _ f l a g s
2022-04-03 12:13:47 +00:00
and #E C O D E
bne e c o d e _ k e y
2022-09-18 12:02:18 +00:00
2022-04-03 12:13:47 +00:00
lda k b _ f l a g s
2021-10-21 07:59:53 +00:00
and #S H I F T
bne s h i f t e d _ k e y
2022-04-03 12:13:47 +00:00
txa
sta k b _ l a s t
2021-10-21 07:59:53 +00:00
lda k e y m a p , x ; map to character code
jmp p u s h _ k e y
2022-04-03 12:13:47 +00:00
ekey_down :
sta k b _ l a s t
lda k b _ f l a g s
ora #E C O D E
sta k b _ f l a g s
jmp e x i t
ecode_key :
txa
sta k b _ l a s t
lda k e y m a p _ e c o d e ,x
jmp p u s h _ k e y
2021-10-21 07:59:53 +00:00
shifted_key :
lda k e y m a p _ s h i f t e d , x ; map to character code
push_key :
ldx k b _ w p t r
sta k b _ b u f f e r , x
inc k b _ w p t r
jmp e x i t
shift_down :
lda k b _ f l a g s
ora #S H I F T
sta k b _ f l a g s
jmp e x i t
key_release :
lda k b _ f l a g s
ora #R E L E A S E
sta k b _ f l a g s
2022-04-03 12:13:47 +00:00
lda k b _ l a s t
cmp #$ e 0
bne e x i t
jmp e k e y _ u p
2021-10-21 07:59:53 +00:00
exit :
2022-07-21 19:36:36 +00:00
rts
2021-10-21 07:59:53 +00:00
; Thanks to Ben Eater for a very useful PS2->Ascii interface
keymap :
2022-07-21 19:36:36 +00:00
.byte " ? " , F9 _ K E Y ," ? " ,$ F A ,$ F C ,$ F E ,$ F D ,F 1 2 _ K E Y ," ? " ,F 1 0 _ K E Y , $ F 7 ,$ F 9 ,$ F B ," ` ? " ; 00-0F
2021-10-21 07:59:53 +00:00
;F1, F2, F3,F4, F5, F6, F7, F8 key bound to $FE, $FD, $FC, $FB, $FA, $F9, $F8, $F7 for no particular reason
.byte " ? ? ? ? ? q1 ? ? ? z s a w2 ? " ; 10-1F
.byte " ? cxde4 3 ? ? v f t r5 ? " ; 20-2F
.byte " ? nbhgy6 ? ? ? m j u 7 8 ? " ; 30-3F
.byte " ? , kio0 9 ? ? . / l ;p-?" ; 40-4F
.byte " ? ? \ ' ? [ = ? ? ? ? " , $ 0 a," ] ? \ \ ? ? " ; 50-5F
.byte " ? ? ? ? ? ? " , $ 0 8 , " ? ? 1 ? 4 7 ? ? ? " ; 60-6F
2022-07-21 19:36:36 +00:00
.byte " 0 .2568 " , ESC_ K E Y ,F 1 1 _ K E Y ," ? + 3 - * 9 ? ? " ; 70-7F
2021-10-21 07:59:53 +00:00
.byte " ? ? ? " , $ F8 ," ? ? ? ? ? ? ? ? ? ? ? ? " ; 80-8F $F8 = F7 key
2022-07-21 19:36:36 +00:00
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; 90-9F
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; A0-AF
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; B0-BF
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; C0-CF
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; D0-DF
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; E0-EF
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; F0-FF
2021-10-21 07:59:53 +00:00
keymap_shifted :
2022-07-21 19:36:36 +00:00
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ," ~ ? " ; 00-0F
2021-10-21 07:59:53 +00:00
.byte " ? ? ? ? ? Q! ? ? ? Z S A W @?" ; 10-1F
.byte " ? CXDE#$ ? ? V F T R % ? " ; 20 - 2 F
.byte " ? NBHGY^ ? ? ? M J U & * ? " ; 30-3F
.byte " ? < KIO) ( ? ? > ? L : P _ ? " ; 40-4F
.byte " ? ? \ " ? { + ? ? ? ? ? } ? | ? ? " ; 50-5F
.byte " ? ? ? ? ? ? ? ? ? 1 ? 4 7 ? ? ? " ; 60-6F
.byte " 0 .2568 ? ? ? + 3 - * 9 ? ? " ; 70-7F
2022-07-21 19:36:36 +00:00
.byte " ? ? ? " , $ F8 ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; 80-8F $F8 = F7 key
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; 90-9F
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; A0-AF
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; B0-BF
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; C0-CF
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; D0-DF
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; E0-EF
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; F0-FF
2022-04-03 12:13:47 +00:00
keymap_ecode :
2022-07-21 19:36:36 +00:00
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; 00-0F
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; 10-1F
2022-09-18 12:02:18 +00:00
.byte $ ED," ^ " ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; 20-2F
2022-07-21 19:36:36 +00:00
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; 30-3F
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; 40-4F
2022-09-18 12:02:18 +00:00
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,' $ ' ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; 50-5F
2022-04-03 12:13:47 +00:00
.byte " 0 1 2 3 4 5 6 7 8 9 A" ,L _ A R R _ K E Y , H O M E _ K E Y , " D E F " ; 60-6F
2022-07-21 19:36:36 +00:00
.byte " 0 1 " , DN_ A R R _ K E Y ," 3 " ,R _ A R R _ K E Y , U P _ A R R _ K E Y , " 6 7 8 9 " ,P G D N _ K E Y ," B " ,P R T S C _ K E Y , P G U P _ K E Y ," E F " ; 70-7F $F6 = PGUP(7D), $F5 = PGDOWN(7A), $F4 = UP Arr.(75), Down arr.(72) = $F3
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; 80-8F $F8 = F7 key
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; 90-9F
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; A0-AF
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; B0-BF
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; C0-CF
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; D0-DF
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; E0-EF
.byte $ ED,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ,$ E D ; F0-FF
2022-09-18 12:02:18 +00:00
;This is a table of all reversed bits - for example $0F is $F0 and $AA is $55.
;We need this to convert the scan code from LSB first to MSB first. The alternative is to rewrite the three tables above -- and I really don't have the patience for that right now.
2022-05-27 15:52:45 +00:00
reversebits :
.byte 0 , 1 2 8 , 6 4 , 1 9 2 , 3 2 , 1 6 0 , 9 6 , 2 2 4 , 1 6 , 1 4 4 , 8 0 , 2 0 8 , 4 8 , 1 7 6 , 1 1 2 , 2 4 0
.byte 8 , 1 3 6 , 7 2 , 2 0 0 , 4 0 , 1 6 8 , 1 0 4 , 2 3 2 , 2 4 , 1 5 2 , 8 8 , 2 1 6 , 5 6 , 1 8 4 , 1 2 0
.byte 2 4 8 , 4 , 1 3 2 , 6 8 , 1 9 6 , 3 6 , 1 6 4 , 1 0 0 , 2 2 8 , 2 0 , 1 4 8 , 8 4 , 2 1 2 , 5 2 , 1 8 0
.byte 1 1 6 , 2 4 4 , 1 2 , 1 4 0 , 7 6 , 2 0 4 , 4 4 , 1 7 2 , 1 0 8 , 2 3 6 , 2 8 , 1 5 6 , 9 2 , 2 2 0 , 6 0
.byte 1 8 8 , 1 2 4 , 2 5 2 , 2 , 1 3 0 , 6 6 , 1 9 4 , 3 4 , 1 6 2 , 9 8 , 2 2 6 , 1 8 , 1 4 6 , 8 2 , 2 1 0 , 5 0
.byte 1 7 8 , 1 1 4 , 2 4 2 , 1 0 , 1 3 8 , 7 4 , 2 0 2 , 4 2 , 1 7 0 , 1 0 6 , 2 3 4 , 2 6 , 1 5 4 , 9 0 , 2 1 8
.byte 5 8 , 1 8 6 , 1 2 2 , 2 5 0 , 6 , 1 3 4 , 7 0 , 1 9 8 , 3 8 , 1 6 6 , 1 0 2 , 2 3 0 , 2 2 , 1 5 0 , 8 6 , 2 1 4
.byte 5 4 , 1 8 2 , 1 1 8 , 2 4 6 , 1 4 , 1 4 2 , 7 8 , 2 0 6 , 4 6 , 1 7 4 , 1 1 0 , 2 3 8 , 3 0 , 1 5 8 , 9 4
.byte 2 2 2 , 6 2 , 1 9 0 , 1 2 6 , 2 5 4 , 1 , 1 2 9 , 6 5 , 1 9 3 , 3 3 , 1 6 1 , 9 7 , 2 2 5 , 1 7 , 1 4 5 , 8 1
.byte 2 0 9 , 4 9 , 1 7 7 , 1 1 3 , 2 4 1 , 9 , 1 3 7 , 7 3 , 2 0 1 , 4 1 , 1 6 9 , 1 0 5 , 2 3 3 , 2 5 , 1 5 3 , 8 9
.byte 2 1 7 , 5 7 , 1 8 5 , 1 2 1 , 2 4 9 , 5 , 1 3 3 , 6 9 , 1 9 7 , 3 7 , 1 6 5 , 1 0 1 , 2 2 9 , 2 1 , 1 4 9 , 8 5
.byte 2 1 3 , 5 3 , 1 8 1 , 1 1 7 , 2 4 5 , 1 3 , 1 4 1 , 7 7 , 2 0 5 , 4 5 , 1 7 3 , 1 0 9 , 2 3 7 , 2 9 , 1 5 7
.byte 9 3 , 2 2 1 , 6 1 , 1 8 9 , 1 2 5 , 2 5 3 , 3 , 1 3 1 , 6 7 , 1 9 5 , 3 5 , 1 6 3 , 9 9 , 2 2 7 , 1 9 , 1 4 7
.byte 8 3 , 2 1 1 , 5 1 , 1 7 9 , 1 1 5 , 2 4 3 , 1 1 , 1 3 9 , 7 5 , 2 0 3 , 4 3 , 1 7 1 , 1 0 7 , 2 3 5 , 2 7
.byte 1 5 5 , 9 1 , 2 1 9 , 5 9 , 1 8 7 , 1 2 3 , 2 5 1 , 7 , 1 3 5 , 7 1 , 1 9 9 , 3 9 , 1 6 7 , 1 0 3 , 2 3 1 , 2 3
.byte 1 5 1 , 8 7 , 2 1 5 , 5 5 , 1 8 3 , 1 1 9 , 2 4 7 , 1 5 , 1 4 3 , 7 9 , 2 0 7 , 4 7 , 1 7 5 , 1 1 1 , 2 3 9
.byte 3 1 , 1 5 9 , 9 5 , 2 2 3 , 6 3 , 1 9 1 , 1 2 7 , 2 5 5
2022-04-03 12:13:47 +00:00
spibyte :
;SR borrowed from http://www.cyberspice.org.uk/blog/2009/08/25/bit-banging-spi-in-6502-assembler/
;I think GW used this way too?
2022-05-27 15:52:45 +00:00
;Bit 5 – MISO (Input data from the peripheral to the computer) ;
;Bit 7 – MOSI (Output data from the computer to the peripheral) We should prefer PB7 to be an output and not use PB6 because of T1 and T2 hw features(T1 out to PB7 and T2 in to PB6)
;Bit 1 – CS (Chip select)
2022-04-03 12:13:47 +00:00
;Bit 0 – SCLK (Output SPI clock)
2022-05-27 15:52:45 +00:00
2022-04-03 12:13:47 +00:00
sta o u t b
2022-05-27 15:52:45 +00:00
2022-04-03 12:13:47 +00:00
lda P O R T B
2022-05-27 15:52:45 +00:00
and #% 01011100
2022-09-18 12:02:18 +00:00
sta S P I T M P ; Save bits not used by SPI
2022-05-27 15:52:45 +00:00
2022-04-03 12:13:47 +00:00
TXA
PHA
TYA
PHA
ldy #0
sty i n b
ldx #8
2022-05-27 15:52:45 +00:00
; sei ; No IRQs during transfer plz
2022-04-03 12:13:47 +00:00
spibytelp :
tya ; (2) set A to 0
asl o u t b ; (5) shift MSB in to carry
bcc s p i b y t e 1 ; (2)
ora #m o s i ; ( 2 ) s e t M O S I i f M S B s e t
spibyte1 :
2022-09-18 12:02:18 +00:00
ora S P I T M P ; Debug - set preserved port B bits. If interrupts are enabled be careful when using this.
2022-04-03 12:13:47 +00:00
sta u s e r v i a ; (4) output (MOSI, SCS low, SCLK low)
tya ; (2) set A to 0 (Do it here for delay reasons)
inc u s e r v i a ; (6) toggle clock high (SCLK is bit 0)
clc ; (2) clear C (Not affected by bit)
2022-05-27 15:52:45 +00:00
;bit uservia ; (4) copy MISO (bit 7) in to N (and MOSI in to V) ; 4 cycles
;bpl spibyte2 ; (2) bvc if miso bit 6, bpl if miso bit 7 ; 2/3 cycles
lda #m i s o ; 2 c y c l e s
and u s e r v i a ; 4 cycles
beq s p i b y t e 2 ; 2/3 cycles
2022-04-03 12:13:47 +00:00
sec ; (2) set C if MISO bit is set (i.e. N) / Or V for miso on bit 6
spibyte2 :
rol i n b ; (5) copy C (i.e. MISO bit) in to bit 0 of result
dec u s e r v i a ; (6) toggle clock low (SCLK is bit 0)
dex ; (2) next bit
bne s p i b y t e l p ; (2) loop
2022-05-27 15:52:45 +00:00
; cli ; IRQs ok from here
2022-04-03 12:13:47 +00:00
PLA
TAY
PLA
TAX
lda i n b ; get result
rts
2022-07-21 19:36:36 +00:00
exitnochange : ; Can jump here from save and load
2022-09-18 12:02:18 +00:00
;lda #0 ; Reset KB pointers
;sta kb_rptr
;sta kb_wptr
;sta scrp
;sta scwp
sec ; Cancel flag
2022-07-21 19:36:36 +00:00
rts
selectbaudrate :
2022-09-18 12:02:18 +00:00
sty T M P 4
2022-07-21 19:36:36 +00:00
jsr P R I M M
2022-09-18 12:02:18 +00:00
.asciiz " Press 1 f o r 3 0 0 b a u d K C S . P r e s s 2 f o r 1 2 0 0 b a u d . \ n "
jsr P R I M M
.asciiz " Press E S C t o c a n c e l . \ n "
jsr c h e c k b o t t o m
;jsr resetkb
2022-07-21 19:36:36 +00:00
waitloop :
jsr w k e y
cmp #$ 31
beq k c s
cmp #$ 32
beq k c s12 0 0
cmp #E S C _ K E Y ; e s c a p e - e x i t
beq e x i t n o c h a n g e
bne w a i t l o o p
kcs :
lda #4
sta P U L S E S L
lda #8
sta P U L S E S H
bne r e a d y t o s a v e ; BRA
kcs1200 :
lda #1
sta P U L S E S L
lda #2
sta P U L S E S H
readytosave :
2022-09-18 12:02:18 +00:00
ldy T M P 4
clc
2022-07-21 19:36:36 +00:00
rts
savetotape :
jsr P R I M M
.asciiz " Ready t o s a v e $ "
2022-09-18 12:02:18 +00:00
dec S H B
2022-07-21 19:36:36 +00:00
lda S H B
2022-09-18 12:02:18 +00:00
;sbc SVPH
2022-07-21 19:36:36 +00:00
jsr p r i n t b y t e
2022-09-18 12:02:18 +00:00
inc S H B
dec S L B
lda S L B
2022-07-21 19:36:36 +00:00
2022-09-18 12:02:18 +00:00
jsr p r i n t b y t e
inc S L B
2022-07-21 19:36:36 +00:00
jsr P R I M M
2022-09-18 12:02:18 +00:00
.asciiz " bytes o f d a t a s t a r t i n g f r o m a d d r e s s $ "
2022-07-21 19:36:36 +00:00
lda S V P H
jsr p r i n t b y t e
lda S V P
jsr p r i n t b y t e
2022-09-18 12:02:18 +00:00
;jsr newline
2022-07-21 19:36:36 +00:00
jsr s e l e c t b a u d r a t e
jsr P R I M M
2022-09-18 12:02:18 +00:00
.asciiz " \ nStart r e c o n t a p e a n d p r e s s E N T E R a f t e r l e a d e r . P r e s s E S C t o c a n c e l . . \ n "
2022-07-21 19:36:36 +00:00
jsr s e t p u l s e s
wrec :
jsr w k e y
cmp #E S C _ K E Y ; e s c a p e - e x i t
beq j m p t o e x i t
cmp #$ 0 A
beq s r e c o r d
bne w r e c ; loop
jmptoexit :
jmp e x i t n o c h a n g e
srecord :
jsr P R I M M
.asciiz " Starting r e c o r d i n g . . . P r e s s a n y k e y t o s t o p . \ n "
clc
lda s c w p
adc #2
waitfor2 :
cmp s c w p
bne w a i t f o r2
2022-09-18 12:02:18 +00:00
lda #0 ; Reset KB pointers
2022-07-21 19:36:36 +00:00
sta k b _ r p t r
sta k b _ w p t r
sta s c r p
sta s c w p
lda A C R
ora #$ C 0 ; Enable T1 PB7 output
sta A C R
lda #0
sta S V P
tay ; IRQ assumes y is 0.
lda #0
sta C B I T
2022-10-18 09:00:00 +00:00
sta B I T N O
2022-07-21 19:36:36 +00:00
lda #135 ; Sine or cosine can be selected by odd or even leader pulses - let's make sure this number is high enough to count as a 7 "1" bits
sta P U L S E S ; Start with leader of x "1" pulses at TIMEOUT interval. This should be followed by #$7F to sync start bit.
lda #1
sta T 1 C H
lda #$ 9 f
sta T 1 C L
lda #$ 80 ; Using the NRZ flag as first byte flag for tx
sta T A P E F L A G S
record :
; Let's do the byte -> tone conversion in IRQ
lda s c r p
cmp s c w p
bne r e c o r d d o n e
bit A C R
bpl f i n i s h e d
bmi r e c o r d
recorddone :
jsr P R I M M
.asciiz " Keyboard i n t e r r u p t . \ n "
LDA #% 01101100
STA A C R ; T1 continuous, T2 count, PB7 disabled, Shift In External
bne i n t e r r u p t e d ; BRA
finished :
jsr P R I M M
.asciiz " Recording f i n i s h e d . \ n "
interrupted :
LDA #< T I M E O U T
STA T 1 L L ; Set low byte of timer1 counter
LDA #> T I M E O U T
STA T 1 L H ; Set high byte of timer1 counter
lda #0 ; Reset KB pointers
sta k b _ r p t r
sta k b _ w p t r
2022-09-18 12:02:18 +00:00
rts
basicsavetotape :
.ifdef BASIC
lda #< R A M S T A R T 2
sta S V P
lda #> R A M S T A R T 2
2022-07-21 19:36:36 +00:00
sta S V P H
2022-09-18 12:02:18 +00:00
sec
;lda VARTAB
.byte $ A5 ; Explicitly using ZP addressing LDA to kill warning
.byte VARTAB
sbc #< R A M S T A R T 2
sta S L B
inc S L B
.byte $ A5
.byte VARTAB+ 1
sbc #> R A M S T A R T 2
2022-07-21 19:36:36 +00:00
sta S H B
2022-09-18 12:02:18 +00:00
inc S H B
jsr s a v e t o t a p e
.endif
2022-07-21 19:36:36 +00:00
rts
2022-09-18 12:02:18 +00:00
basicloadfromtape :
.ifdef BASIC
lda #< R A M S T A R T 2
sta S V P
lda #> R A M S T A R T 2
sta S V P H
jsr l o a d f r o m t a p e
lda S V P
.byte $ 8 5
.byte VARTAB
lda S V P H
.byte $ 8 5
.byte VARTAB+ 1
.endif
rts
; FIX HARDCODED ADDRESSES HERE!
2022-07-21 19:36:36 +00:00
loadfromtape :
jsr P R I M M
2022-09-18 12:02:18 +00:00
.asciiz " Loading f r o m t a p e . \ n "
2022-07-21 19:36:36 +00:00
jsr s e l e c t b a u d r a t e
2022-09-18 12:02:18 +00:00
bcs s t a t u s l o o p
2022-07-21 19:36:36 +00:00
ldx #0
txa
cleardata :
sta $ 1 0 0 0 ,x
dex
bne c l e a r d a t a
lda #$ F F
sta T 1 L L
sta T 1 L H
2022-09-18 12:02:18 +00:00
sta T 1 C H ; This should reset T1?
2022-07-21 19:36:36 +00:00
sta R X B Y T E
; Activate CA1 irq to trigger IRQ
2022-09-18 12:02:18 +00:00
lda #$ 82 ; S+CA1 bit
2022-07-21 19:36:36 +00:00
sta I E R
; Receive data in irq
lda #0
;stx CBIT
;sta TAPEFLAGS
sta p l z p n t
sta P U L S E S
sta o n e s i n a r o w
lda #8
sta C B I T
2022-10-18 09:00:00 +00:00
lda #2
2022-09-18 12:02:18 +00:00
sta L O A D T I M E O U T
2022-07-21 19:36:36 +00:00
lda #$ 32
sta p l z p n t + 1
lda #$ f f
sta N R Z B Y T E
jsr P R I M M
.asciiz " Press p l a y o n t a p e ! \ n "
; Write status here
statusloop :
2022-09-18 12:02:18 +00:00
lda L O A D T I M E O U T
bne n o p r o b l e m
lda T A P E F L A G S
and #$ 20
beq t i m e o u t
lda #3
sta L O A D T I M E O U T
noproblem :
2022-07-21 19:36:36 +00:00
lda T A P E F L A G S
and #$ 20
beq n o l e a d e r
jsr P R I M M ;
2022-09-18 12:02:18 +00:00
.asciiz " Got l e a d e r . \ n "
2022-07-21 19:36:36 +00:00
lda T A P E F L A G S
and #% 11011111 ;
sta T A P E F L A G S
noleader :
2022-09-18 12:02:18 +00:00
lda S V P
2022-10-18 09:00:00 +00:00
.ifdef BASIC
2022-09-18 12:02:18 +00:00
cmp #< R A M S T A R T 2
bne n o z
lda S V P H
cmp #> R A M S T A R T 2
beq n o t s t a r t e d
2022-10-18 09:00:00 +00:00
.else
cmp #< 1000
bne n o z
lda S V P H
cmp #> 1000
beq n o t s t a r t e d
.endif
2022-09-18 12:02:18 +00:00
noz :
lda C R S R P N T
and #% 11000000 ; keep only section bits
ora #L I N E S T A R T ;
sta C R S R P N T
ldy #0
lda #' $ '
jsr p r i n t f a s t
sec
lda S V P H
2022-10-18 09:00:00 +00:00
.ifdef BASIC
2022-09-18 12:02:18 +00:00
sbc #> R A M S T A R T 2
jsr p r i n t b y t e
lda S V P
sbc #< R A M S T A R T 2
2022-10-18 09:00:00 +00:00
.else
sbc #> 1000
jsr p r i n t b y t e
lda S V P
sbc #< 1000
.endif
2022-09-18 12:02:18 +00:00
jsr p r i n t b y t e
jsr P R I M M
.asciiz " bytes r e c e i v e d "
2022-07-21 19:36:36 +00:00
2022-09-18 12:02:18 +00:00
notstarted :
lda #0
jsr c h e c k k e y b o a r d
beq l 2 0 2 0
lda k b _ b u f f e r ,x
inc k b _ r p t r
cmp #E S C _ K E Y
beq e x i t u s e r l a n d
l2020 :
2022-07-21 19:36:36 +00:00
lda I E R
and #2
2022-09-18 12:02:18 +00:00
beq t i m e o u t
jmp s t a t u s l o o p
2022-07-21 19:36:36 +00:00
; Disable CA1 in IRQ on timeout
2022-09-18 12:02:18 +00:00
timeout :
jsr P R I M M
2022-10-18 09:00:00 +00:00
.asciiz " \ nFinished l o a d i n g . \ n "
2022-07-21 19:36:36 +00:00
exituserland :
2022-09-18 12:02:18 +00:00
lda #2 ; Disable CA1
2022-07-21 19:36:36 +00:00
sta I E R
lda #0
sta T A P E F L A G S
lda #< T I M E O U T
sta T 1 L L
lda #> T I M E O U T
sta T 1 L H
2022-09-18 12:02:18 +00:00
sta T 1 C H
2022-07-21 19:36:36 +00:00
rts
ca1irq :
2022-09-18 12:02:18 +00:00
bit P O R T A ; Clear IRQ flag
2022-07-21 19:36:36 +00:00
inc P U L S E S
readtime :
ldx T 1 C H
lda T 1 C L
cpx T 1 C H
bne r e a d t i m e
2022-09-18 12:02:18 +00:00
sta C T 1 L ; T1CL
stx C T 1 H ; T1CH
2022-07-21 19:36:36 +00:00
sec
2022-09-18 12:02:18 +00:00
lda L T 1 L ; Last T1CL
sbc C T 1 L ; Current T1CL
2022-07-21 19:36:36 +00:00
sta p l s p e r i o d
2022-09-18 12:02:18 +00:00
lda L T 1 H ; Last T1CH
sbc C T 1 H ; Current T1CH
2022-07-21 19:36:36 +00:00
sta p l s p e r i o d + 1 ; ResultH
lda T A P E F L A G S
bpl d o n e d e b u g ; Only KCS, no need for the block below
; if last == 1 and this == 0 and pulses == 2 then insert 1 and proceed
lda T M P
and #1
beq n e v e r m i n d
clc
lda p l s p e r i o d
adc #$ 40 ; Add some negative hysteresis
sta p l s p e r i o d
bcc n m
inc p l s p e r i o d + 1
nm :
lda P U L S E S
cmp #2
bne n e v e r m i n d
lda p l s p e r i o d + 1
cmp #5
bcc n e v e r m i n d
bne d o i t ; Higher than 5 so def. a 0
lda p l s p e r i o d
cmp #$ 08
bcc n e v e r m i n d ; This was a 1, not a 0 after all
doit :
sec
jsr s a v e b i t
inc P U L S E S
nevermind :
lda p l s p e r i o d + 1
;Debug
; ldy #0
; sta (plzpnt),y
; inc plzpnt
; bne lbyte
; inc plzpnt+1
; lbyte:
; lda plsperiod
; sta (plzpnt),y
; inc plzpnt
; bne donedebug
; inc plzpnt+1
donedebug :
2022-09-18 12:02:18 +00:00
stx L T 1 H
lda C T 1 L
sta L T 1 L
2022-07-21 19:36:36 +00:00
lda p l s p e r i o d + 1
cmp #6
bcs w a s0 ; Definitely a 0, skip extra check
cmp #5 ; Should compare 16 bits instead of MSB, should compare to an avg of 8 "1"s.. But for now this is fine for 1200/~2400Hz
;bcc was1 ; Was 1 (4 or less) Fall through instead
bcs m a y b e 0 ; Was 0 (5 or more)
was1 :
bit T A P E F L A G S ; Check NRZ
bpl c h e c k p u l s e s
noextra :
inc o n e s i n a r o w ; This is only relevant for 1200/2200Hz modulation
lda o n e s i n a r o w
cmp #9 ; Correct for the fact that the 5th one pulse is missing it's companion within the bit period at 2200Hz instead of 2400Hz
bne c h e c k p u l s e s
inc P U L S E S
lda #0
sta o n e s i n a r o w
checkpulses :
lda P U L S E S
cmp P U L S E S H
bcc l 8 r
gtsb :
sec
jsr s a v e b i t
l8r :
sec
bcs p r i n t e d ; BRA
maybe0 :
bit T A P E F L A G S ; Check NRZ
bpl w a s0
lda p l s p e r i o d
cmp #$ 30
bcc w a s1 ; Low byte indicates this was in fact not a 0
lda p l s p e r i o d + 1
was0 :
cmp #9
bcs j u n k ; junk = noErrC, over = badErrC
corrected :
lda #0
sta o n e s i n a r o w
lda P U L S E S
cmp P U L S E S L
bcc l 0 r
clc
jsr s a v e b i t
l0r :
clc
bcc p r i n t e d ; BRA
junk :
lda #0
sta P U L S E S
sta o n e s i n a r o w
beq g t x ; BRA
printed :
rol T M P ; Save carry bit for next round
gtx :
jmp e x i t i r q ; IRQ exit in ROM
2022-10-18 09:00:00 +00:00
checkstart :
lda #0
plp
ror
beq a f t e r n o s a v e
jmp m o r e b i t s ; Bad start bit
2022-07-21 19:36:36 +00:00
savebit :
2022-10-18 09:00:00 +00:00
php ; Save carry
lda C B I T
cmp #11 ; Check start bit
beq c h e c k s t a r t
cmp #2 ; Throw away parity
beq n o s a v e
cmp #1 ; Throw away stop
beq n o s a v e
plp
2022-07-21 19:36:36 +00:00
ror R X B Y T E ; Shift in bit from carry
2022-10-18 09:00:00 +00:00
jmp a f t e r n o s a v e
nosave :
plp
afternosave :
2022-07-21 19:36:36 +00:00
bit T A P E F L A G S
2022-10-18 09:00:00 +00:00
2022-07-21 19:36:36 +00:00
;Tapeflags
;$80 = nrzbit
;$40 = startbyte received
bpl r s t p l s s ; Not saving NRZ too
lda R X B Y T E
cmp #$ 7 E
beq m o r e b i t s
clc
and #$ 80
rol
rol
sta ( p l z p n t ) ,y
inc p l z p n t
bne r s t p l s s
inc p l z p n t + 1
rstplss :
lda #0
sta P U L S E S
bit T A P E F L A G S
;Tapeflags
;$80 = nrzbit
;$40 = startbyte received
bpl c h e c k l e a d e r ; Not saving NRZ too
ldy N R Z B Y T E ; Backup
lda R X B Y T E
;cmp #$FE ; Check for another "flag" byte FE == 7E NRZ
;beq aprsleader
and #$ C 0 ; Top two bits
beq o n e ; AND 0 == both bits zero
cmp #$ C 0
beq o n e ; CMP 0 = C0 = both bits 1
zero :
clc
bcc a f t e r o n e ; BRA
one :
sec
afterone :
ror N R Z B Y T E ; Shift in carry
; Unstuffing
;bit TAPEFLAGS
;bvc printnrz ; Skip if not saving
lda N R Z B Y T E
cmp #$ 7 E
beq a p r s l e a d e r
ldy #0
;sec
;bcs morebits
printnrz :
ldy #0
;inc $10e0
; lda NRZBYTE
; cmp #$7E
; beq aprsleader
bit T A P E F L A G S
bvs s a v e
bvc m o r e b i t s
checkleader :
bvs s a v e ; Already saving
lda R X B Y T E
cmp #$ 7 F
beq k c s l e a d e r
;cmp #$FE ; FE == E7 in NRZ
;beq aprsleader
rts ; Don't want to fall through
2022-10-18 09:00:00 +00:00
2022-07-21 19:36:36 +00:00
save :
dec C B I T
bne m o r e b i t s
;lda RXBYTE
savebyte :
lda T A P E F L A G S
bpl s a v e k c s
; Not for KCS stuff
and #$ 04
beq n o s h i f t
lda N R Z B Y T E
lsr ; Addresses are left shifted
jmp s h i f t e d
noshift :
lda N R Z B Y T E
shifted :
sta ( p l z p n t ) ,y
inc p l z p n t
bne r p l s s
inc p l z p n t + 1
savekcs :
lda R X B Y T E
rplss :
2022-09-18 12:02:18 +00:00
ldy #0
2022-07-21 19:36:36 +00:00
sta ( S V P ) ,y
inc S V P
bne s a m e p a g e
inc S V P H
samepage :
2022-09-18 12:02:18 +00:00
;jsr printbyte
2022-07-21 19:36:36 +00:00
;lda #' '
;jsr printk
2022-10-18 09:00:00 +00:00
; Here we should decide if we're going for 8 or 11 bits - buts lets assume 11.
lda #11
2022-07-21 19:36:36 +00:00
sta C B I T
morebits :
rts
kcsleader :
lda T A P E F L A G S
ora #$ 60 ; Set leader flag
sta T A P E F L A G S
2022-10-18 09:00:00 +00:00
lda #10 ; First time we already have the start bit
2022-07-21 19:36:36 +00:00
sta C B I T
rts
aprsleader :
bit T A P E F L A G S
bvs s a v e b y t e
lda T A P E F L A G S
ora #$ e 4 ; NRZ and save bits
sta T A P E F L A G S
bne s a v e b y t e ; BRA
simpledelay :
ldx #0
delay :
dex
NOP
NOP
NOP
NOP
NOP
NOP
bne d e l a y
rts
2022-10-18 09:00:00 +00:00
2022-05-27 15:52:45 +00:00
i2c_start : ; Let's assume i2c addr is in A and RW bit is in C
rol ; Move address to top bits and RW bit to bit0
sta o u t b ; Save addr + rw bit
lda #S C L _ I N V ; S t a r t w i t h S C L a s I N P U T H I G H
and D D R B
sta D D R B
lda #S D A ; I n s u r e S D A i s o u t p u t l o w b e f o r e S C L i s L O W
ora D D R B
sta D D R B
lda #S D A _ I N V
and P O R T B
sta P O R T B
lda #S C L _ I N V
and P O R T B
sta P O R T B
2022-10-18 09:00:00 +00:00
lda D D R B
ora #S C L
sta D D R B ; Set SCL LOW by setting it to OUTPUT
2022-05-27 15:52:45 +00:00
; Fall through to send address + RW bit
; From here on we can assume OUTPUTs are LOW and INPUTS are HIGH.
; Maybe some of the juggling above is not necessary but let's not assume for now
i2cbyteout :
lda #S D A _ I N V ; I n c a s e t h i s i s a d a t a b y t e w e s e t S D A L O W
and P O R T B
sta P O R T B
ldx #8
i2caddrloop : ; At start of loop SDA and SCL are both OUTPUT LOW
asl o u t b ; Put MSB in carry
2022-10-18 09:00:00 +00:00
lda D D R B
ora #S C L
sta D D R B ; Set SCL LOW by setting it to OUTPUT
2022-05-27 15:52:45 +00:00
bcc s e t i 2 c b i t 0 ; If data bit was low
lda D D R B ; else set it high
and #S D A _ I N V
sta D D R B
2022-07-21 19:36:36 +00:00
bcs w a s o n e ; BRA
2022-05-27 15:52:45 +00:00
seti2cbit0 :
lda D D R B
ora #S D A
sta D D R B
2022-07-21 19:36:36 +00:00
wasone :
2022-10-18 09:00:00 +00:00
lda D D R B
and #S C L _ I N V
sta D D R B ; Set SCL HIGH by setting it to input; Let SCL go HIGH by setting it to input
2022-05-27 15:52:45 +00:00
dex
bne i 2 c a d d r l o o p
2022-10-18 09:00:00 +00:00
lda D D R B
ora #S C L
sta D D R B ; Set SCL LOW by setting it to OUTPUT ; Set SCL low after last bit
2022-05-27 15:52:45 +00:00
lda D D R B ; Set SDA to INPUT
and #S D A _ I N V
sta D D R B
2022-10-18 09:00:00 +00:00
lda D D R B
and #S C L _ I N V
sta D D R B ; Set SCL HIGH by setting it to input
2022-05-27 15:52:45 +00:00
; NOP here?
lda P O R T B ; Check ACK bit
clc
and #S D A
bne n a c k
sec ; Set carry to indicate ACK
nack :
2022-10-18 09:00:00 +00:00
lda D D R B
ora #S C L
sta D D R B ; Set SCL LOW by setting it to OUTPUT
2022-05-27 15:52:45 +00:00
rts
i2cbytein : ; Assume SCL is LOW
lda D D R B ; Set SDA to input
and #S D A _ I N V
sta D D R B
2022-10-18 09:00:00 +00:00
lda #0
sta i n b
2022-05-27 15:52:45 +00:00
ldx #8
byteinloop :
clc ; Clearing here for more even cycle
2022-10-18 09:00:00 +00:00
lda D D R B
and #S C L _ I N V
sta D D R B ; Set SCL HIGH by setting it to input
nop
2022-05-27 15:52:45 +00:00
lda P O R T B
and #S D A
beq g o t 0
sec
got0 :
rol i n b ; Shift carry into input byte
2022-10-18 09:00:00 +00:00
lda D D R B
ora #S C L
sta D D R B ; Set SCL LOW by setting it to OUTPUT
2022-05-27 15:52:45 +00:00
dex
bne b y t e i n l o o p
2022-10-18 09:00:00 +00:00
lda D D R B ; Send NACK == SDA high (because we're ony fetching single bytes)
2022-05-27 15:52:45 +00:00
and #S D A _ I N V
sta D D R B
2022-10-18 09:00:00 +00:00
lda D D R B
and #S C L _ I N V
sta D D R B ; Set SCL HIGH by setting it to input
lda D D R B
ora #S C L
sta D D R B ; Set SCL LOW by setting it to OUTPUT
2022-05-27 15:52:45 +00:00
rts ; Input byte in inb
i2c_stop :
lda D D R B ; SDA low
ora #S D A
sta D D R B
2022-10-18 09:00:00 +00:00
lda D D R B
and #S C L _ I N V
sta D D R B ; Set SCL HIGH by setting it to input
nop
nop
2022-05-27 15:52:45 +00:00
lda D D R B ; Set SDA high after SCL == Stop condition.
and #S D A _ I N V
sta D D R B
rts
i2c_test :
2022-10-18 09:00:00 +00:00
;lda #$77 ; Address $77 = BMP180 address
lda I 2 C A D D R
2022-05-27 15:52:45 +00:00
clc ; Write
jsr i 2 c _ s t a r t
; Fail check here. C == 1 == ACK
bcc f a i l e d
2022-10-18 09:00:00 +00:00
;lda #$D0 ; BMP180 register $D0 == chipID == $55
lda I 2 C R E G ; VGA screen EDID usually has address $50
2022-05-27 15:52:45 +00:00
sta o u t b
jsr i 2 c b y t e o u t
2022-10-18 09:00:00 +00:00
;lda #$77 ; Address
lda I 2 C A D D R
2022-05-27 15:52:45 +00:00
sec ; Read
jsr i 2 c _ s t a r t
jsr i 2 c b y t e i n
jsr i 2 c _ s t o p
2022-10-18 09:00:00 +00:00
lda i n b
sec
rts
2022-05-27 15:52:45 +00:00
failed :
2022-10-18 09:00:00 +00:00
lda #0
rts
i2c_read :
lda I 2 C A D D R
clc ; We "write" the address we want to read from
jsr i 2 c _ s t a r t
bcc r e a d f a i l
lda #0
sta o u t b
jsr i 2 c b y t e o u t
jsr i 2 c _ s t o p
lda I 2 C A D D R
sec ; Now we read the register data
jsr i 2 c _ s t a r t
jsr i 2 c b y t e i n
jsr i 2 c _ s t o p
lda i n b
readfail :
2022-05-27 15:52:45 +00:00
rts
2022-10-18 09:00:00 +00:00
2022-05-27 15:52:45 +00:00
2022-09-18 12:02:18 +00:00
rubout :
ldy #0
lda C R S R C H R
sta ( C R S R P N T ) ,y
normcrsr :
dec C R S R P N T
lda C R S R P N T
cmp #255
bne n o t u n d e r
dec C R S R P N T 2
notunder :
lda #' '
sta ( C R S R P N T ) ,y
dec k b _ r p t r
dec k b _ w p t r
dec k b _ w p t r
rts
2022-05-27 15:52:45 +00:00
2022-04-03 12:13:47 +00:00
rf_nop :
lda P O R T B
and #% 11111101 ; Set CS Low
sta P O R T B
lda #$ F F
jsr s p i b y t e
sta R F _ S T S
lda P O R T B
ora #2 ; Set CS high
sta P O R T B
rts
;rw_reg takes command in x and data in A. Returns data in A.
rw_reg :
pha
lda P O R T B
and #% 11111101 ; Set CS Low
sta P O R T B
txa
jsr s p i b y t e
sta R F _ S T S
pla
jsr s p i b y t e
; A has return value
pha
lda P O R T B
ora #2 ; Set CS high
sta P O R T B
pla ; A has return value
rts
initrf24 :
ldx #$ E 2 ; Flush RX
lda #0
jsr r w _ r e g
ldx #$ 27 ; Clear RX_DR - $20 | $07, write address $07
lda #$ 40 ; %01000000 RX_DR mask
jsr r w _ r e g
ldx #$ 3 D ; Set FEATURE register - $20 | $1D, write address $1D
lda #4
jsr r w _ r e g
ldx #$ 3 C ; Set DYNDP register
lda #$ 3 F
jsr r w _ r e g
ldx #$ 20 ; Power up, RX
lda #$ 0 F
jsr r w _ r e g
lda P O R T B ; Set CE high
ora #4 ; CE is PB.2
sta P O R T B
rts
readrf24regs :
ldx #31
readrf24 :
lda #0 ; Let's read first byte of all registers
jsr r w _ r e g
2022-09-18 12:02:18 +00:00
sta R F 2 4 R E G S ,x
2022-04-03 12:13:47 +00:00
dex
bpl r e a d r f24
rts
getmessage :
; Here we read the msg
ldx #$ 60 ; Get top of RX fifo length - R_RX_PL_WID
lda #0
jsr r w _ r e g
2022-09-18 12:02:18 +00:00
sta R F 2 4 R E G S + $ 1 1 ;$81 ; Overwrite P0 payload length location in mem
2022-04-03 12:13:47 +00:00
ldy #0
lda P O R T B
and #% 11111101 ; Set CS Low
sta P O R T B
readpayload :
lda #$ 61
jsr s p i b y t e
sta R F _ S T S
bytes :
jsr s p i b y t e
2022-09-18 12:02:18 +00:00
sta M S G B U F , y ;
2022-04-03 12:13:47 +00:00
iny
2022-09-18 12:02:18 +00:00
cpy R F 2 4 R E G S + $ 1 1
2022-04-03 12:13:47 +00:00
bne b y t e s
lda P O R T B
ora #2 ; Set CS high
sta P O R T B
ldx #$ 27 ; Clear RX_DR
lda #$ 40
jsr r w _ r e g
rts
2022-07-21 19:36:36 +00:00
; Wait for keypress subroutine -
wkey :
2022-09-18 12:02:18 +00:00
jsr c h e c k k e y b o a r d
beq w k e y
2022-07-21 19:36:36 +00:00
havekey :
lda k b _ b u f f e r , x
inc k b _ r p t r
rts
2022-09-18 12:02:18 +00:00
delay20ms :
ldx M I L L I S H
lda M I L L I S
cpx M I L L I S H
bne d e l a y 2 0 m s ; In case we hit bad cycle
clc
adc #5 ; 20ms
bcc s t a l l h e r e
inx
stallhere :
cpx M I L L I S H
bne s t a l l h e r e
cmp M I L L I S
bne s t a l l h e r e
rts
2022-07-21 19:36:36 +00:00
setpulses :
; Here we load some default values if not specified something non-zero
lda P U L S E S L ; Number of pulses pr lower frequency bit
bne s p l s h
lda #K C S 300 P L ; == 4 == 1200 Hz / 4 == 300 baud
sta P U L S E S L
splsh :
lda P U L S E S H
bne p l s s
lda #K C S 300 P H ; == 8 == 2400 Hz / 8 == 300 baud
sta P U L S E S H
plss :
rts
2022-04-03 12:13:47 +00:00
2022-09-18 12:02:18 +00:00
; APPLE := 1
; .include "msbasic/defines_apple.s"
.ifdef BASIC
OSI : = 1
.include " defines_ a b n 6 5 0 2 . s "
;CBM2 := 1
;.include "msbasic/defines_cbm2.s"
;KIM := 1
;.include "msbasic/defines_kim.s"
.include " msbasic/ m s b a s i c . s "
; lda #LIST
.else
.segment " INIT"
.segment " HEADER"
.segment " VECTORS"
.segment " KEYWORDS"
.segment " ERROR"
.segment " CODE"
.segment " CHRGET"
.segment " EXTRA"
.segment " DUMMY"
.endif
2022-04-03 12:13:47 +00:00
; Inline printing routine from http://6502.org/source/io/primm.htm
.segment " PRIMM"
.org $ ffc8
PRIMM :
PHA ; save A
TYA ; copy Y
PHA ; save Y
TXA ; copy X
PHA ; save X
TSX ; get stack pointer
LDA $ 0 1 0 4 ,X ; get return address low byte (+4 to
; correct pointer)
2022-09-18 12:02:18 +00:00
STA P R I M M Z P 1 ; save in page zero
2022-04-03 12:13:47 +00:00
LDA $ 0 1 0 5 ,X ; get return address high byte (+5 to
; correct pointer)
2022-09-18 12:02:18 +00:00
STA P R I M M Z P 2 ; save in page zero
2022-04-03 12:13:47 +00:00
LDY #$ 01 ; set index (+1 to allow for return
; address offset)
PRIM2 :
2022-09-18 12:02:18 +00:00
LDA ( P R I M M Z P 1 ) ,Y ; get byte from string
2022-04-03 12:13:47 +00:00
BEQ P R I M 3 ; exit if null (end of text)
JSR p r i n t k ; else display character
INY ; increment index
BNE P R I M 2 ; loop (exit if 256th character)
PRIM3 :
TYA ; copy index
CLC ; clear carry
2022-09-18 12:02:18 +00:00
ADC P R I M M Z P 1 ; add string pointer low byte to index
2022-04-03 12:13:47 +00:00
STA $ 0 1 0 4 ,X ; put on stack as return address low byte
; (+4 to correct pointer, X is unchanged)
LDA #$ 00 ; clear A
2022-09-18 12:02:18 +00:00
ADC P R I M M Z P 2 ; add string pointer high byte
2022-04-03 12:13:47 +00:00
STA $ 0 1 0 5 ,X ; put on stack as return address high byte
; (+5 to correct pointer, X is unchanged)
PLA ; pull value
TAX ; restore X
PLA ; pull value
TAY ; restore Y
PLA ; restore A
RTS
2021-10-21 07:59:53 +00:00
2022-09-18 12:02:18 +00:00
.segment " VECTORS6 5 0 2 "
2021-10-21 07:59:53 +00:00
.ORG $ fffa
.word nmi,r e s e t ,i r q
.reloc