refactor with source+header
This commit is contained in:
parent
321759f70d
commit
9a1324a29a
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
**.bin
|
**.bin
|
||||||
**.o
|
**.o
|
||||||
.build
|
**.d
|
||||||
.dependencies
|
*build*
|
||||||
|
labels
|
||||||
|
51
Makefile
51
Makefile
@ -1,41 +1,54 @@
|
|||||||
ROM = ../rom.bin
|
ROM = ../rom.bin
|
||||||
|
|
||||||
BUILD_DIR = .build
|
OBJ_DIR = build
|
||||||
|
|
||||||
SRC_DIRS = programs system
|
SRC_DIRS = . programs system util
|
||||||
|
|
||||||
# VASM = ~/6502/vasm6502
|
# VASM = ~/6502/vasm6502
|
||||||
ASM = ca65
|
ASM = ca65
|
||||||
ASMFLAGS = -g --cpu 65C02 $(foreach srcdir, $(SRC_DIRS), -I $(srcdir))
|
ASMFLAGS = -g --cpu 65C02 $(foreach srcdir, $(SRC_DIRS), -I $(srcdir))
|
||||||
ASMDEPFLAGS = --create-dep .dependencies
|
|
||||||
|
|
||||||
LD = ld65
|
LD = ld65
|
||||||
LDFLAGS = -C linker.conf
|
LDFLAGS = -C linker.conf --obj-path $(OBJ_DIR) -Ln labels
|
||||||
|
|
||||||
|
SRC = $(wildcard *.s65) $(wildcard */*.s65)
|
||||||
|
OBJ = $($(notdir SRC):%.s65=$(OBJ_DIR)/%.o)
|
||||||
|
OBJ_DIRS = $(OBJ_DIR) $(foreach dir_,$(SRC_DIRS),$(OBJ_DIR)/$(dir_))
|
||||||
|
DEP = $(wildcard $(OBJ_DIR)/*/*.d)
|
||||||
|
|
||||||
# DEPENDS = $(shell $(VASM) -depend=make $(MAIN))
|
# DEPENDS = $(shell $(VASM) -depend=make $(MAIN))
|
||||||
|
|
||||||
-include .dependencies
|
-include $(DEP)
|
||||||
|
|
||||||
$(BUILD_DIR):
|
.PHONY: default test clean print
|
||||||
mkdir $@
|
|
||||||
|
|
||||||
.PHONY: default test clean
|
|
||||||
.DEFAULT_GOAL = default
|
.DEFAULT_GOAL = default
|
||||||
default: $(ROM)
|
|
||||||
|
FMT_MESSAGE="\e[1;34m%s\e[0m %s\n"
|
||||||
|
FMT_ASM="\e[1;34mAssembling\e[0m: \e[34m%s\e[39m from %s\e[0m\n"
|
||||||
|
FMT_VAR="\e[1;35m%s\e[0m: %s\n"
|
||||||
|
|
||||||
test: ../test.bin
|
test: ../test.bin
|
||||||
|
print:
|
||||||
|
@printf $(FMT_VAR) "ASMFLAGS" "$(ASMFLAGS)"
|
||||||
|
@printf $(FMT_VAR) "LDFLAGS" "$(LDFLAGS)"
|
||||||
|
@printf $(FMT_VAR) "SRC" "$(SRC)"
|
||||||
|
@printf $(FMT_VAR) "OBJ" "$(OBJ)"
|
||||||
|
default: $(ROM)
|
||||||
|
|
||||||
|
$(OBJ_DIRS):
|
||||||
|
mkdir -p $@
|
||||||
|
|
||||||
$(ROM): $(BUILD_DIR)/main.o
|
$(ROM): $(OBJ)
|
||||||
|
@printf $(FMT_MESSAGE) "Linking" "$@"
|
||||||
|
$(LD) $(LDFLAGS) $(OBJ) -o $@
|
||||||
|
|
||||||
|
../test.bin: $(OBJ_DIR)/test.o
|
||||||
$(LD) $(LDFLAGS) $< -o $@
|
$(LD) $(LDFLAGS) $< -o $@
|
||||||
|
|
||||||
../test.bin: $(BUILD_DIR)/test.o
|
$(OBJ_DIR)/%.o: %.s65 | $(OBJ_DIRS)
|
||||||
# $(VASM) -dotdir -opt-branch -wdc02 -chklabels test.asm6502
|
@printf $(FMT_ASM) "$@" "$<"
|
||||||
$(LD) $(LDFLAGS) $(BUILD_DIR)/test.o -o ../test.bin
|
$(ASM) $(ASMFLAGS) --create-dep $(patsubst %.o,%.d,$@) $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: %.s65 | $(BUILD_DIR)
|
|
||||||
$(ASM) $(ASMFLAGS) $(ASMDEPFLAGS) $< -o $@
|
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -r $(BUILD_DIR)
|
rm -r $(OBJ_DIR)
|
||||||
rm $(ROM)
|
rm $(ROM)
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
MEMORY {
|
MEMORY {
|
||||||
RAM_ZP: start = $0000, size = $100, type = rw, file = "", fill = yes;
|
RAM_ZP: start = $0000, size = $0100, type = rw, file = "", fill = yes;
|
||||||
# RAM: start = $0100, size = $5eff, type = rw, file = "", fill = yes;
|
# RAM: start = $0100, size = $5eff, type = rw, file = "", fill = yes;
|
||||||
RAM: start = $0100, size = $4eff, type = rw, file = "", fill = yes;
|
STACK: start = $0100, size = $0100, type = rw, file = "", fill = yes;
|
||||||
|
RAM: start = $0200, size = $4e00, type = rw, file = "", fill = yes;
|
||||||
SPI: start = $5000, size = $1000, type = rw, file = "spi.bin", fill = no;
|
SPI: start = $5000, size = $1000, type = rw, file = "spi.bin", fill = no;
|
||||||
VIA1: start = $6000, size = $600f, type = rw, file = "", fill = yes;
|
VIA1: start = $6000, size = $000f, type = rw, file = "", fill = yes;
|
||||||
VIA2: start = $7000, size = $700f, type = rw, file = "", fill = yes;
|
VIA2: start = $7000, size = $000f, type = rw, file = "", fill = yes;
|
||||||
ROM: start = $8000, size = $8000, type = ro, file = %O, fill = yes;
|
ROM: start = $8000, size = $8000, type = ro, file = %O, fill = yes;
|
||||||
}
|
}
|
||||||
SEGMENTS {
|
SEGMENTS {
|
||||||
|
47
main.s65
47
main.s65
@ -1,4 +1,8 @@
|
|||||||
.include "system/system.s65"
|
.include "system/system.h65"
|
||||||
|
.export home
|
||||||
|
.import printer:absolute
|
||||||
|
.import spi_menu:absolute
|
||||||
|
|
||||||
.code
|
.code
|
||||||
|
|
||||||
.macro DEBUG_LED_OFF nr
|
.macro DEBUG_LED_OFF nr
|
||||||
@ -30,18 +34,17 @@
|
|||||||
;********************************************************************************
|
;********************************************************************************
|
||||||
; LCD
|
; LCD
|
||||||
; .include "utility.asm6502"
|
; .include "utility.asm6502"
|
||||||
LCD_IO = IO1
|
; LCD_IO = IO1
|
||||||
.include "system/lcd.s65"
|
.include "system/lcd.h65"
|
||||||
; Keypad Reading
|
; Keypad Reading
|
||||||
KP_IO = IO2
|
; KP_IO = IO2
|
||||||
.include "system/keypad.s65"
|
.include "system/keypad.h65"
|
||||||
; SPI
|
; SPI
|
||||||
SPI_IO = IO2
|
.include "system/spi.h65"
|
||||||
.include "system/spi.s65"
|
|
||||||
; Printer
|
; Printer
|
||||||
.include "programs/printer.s65"
|
; .include "programs/printer.s65"
|
||||||
.include "programs/print_slow.s65"
|
.include "programs/print_slow.s65"
|
||||||
.include "programs/spi-menu.s65"
|
; .include "programs/spi-menu.s65"
|
||||||
; Digital Humidity and Temerature Sensor
|
; Digital Humidity and Temerature Sensor
|
||||||
; .include "dht.s65"
|
; .include "dht.s65"
|
||||||
|
|
||||||
@ -54,7 +57,7 @@ IRQ_VAR: .res 1
|
|||||||
.code
|
.code
|
||||||
nmi:
|
nmi:
|
||||||
lda #'%'
|
lda #'%'
|
||||||
jsr lcd_char
|
jsr lcd::print_char
|
||||||
rti
|
rti
|
||||||
irq:
|
irq:
|
||||||
; read IRFs, while bit 7 ist set handle interrupts
|
; read IRFs, while bit 7 ist set handle interrupts
|
||||||
@ -69,7 +72,7 @@ irq:
|
|||||||
bbs2 IRQ_VAR,@irq_spi_p ; check SR
|
bbs2 IRQ_VAR,@irq_spi_p ; check SR
|
||||||
bbs1 IRQ_VAR,@irq_keypad ; check CA1
|
bbs1 IRQ_VAR,@irq_keypad ; check CA1
|
||||||
; this should never be reached
|
; this should never be reached
|
||||||
jsr lcd_clear
|
jsr lcd::clear
|
||||||
Print str_irq_unknown
|
Print str_irq_unknown
|
||||||
; force reset interrupt flags
|
; force reset interrupt flags
|
||||||
lda #$ff
|
lda #$ff
|
||||||
@ -77,7 +80,7 @@ irq:
|
|||||||
sta IO2 + IO::IFR
|
sta IO2 + IO::IFR
|
||||||
bra @irq_return
|
bra @irq_return
|
||||||
@irq_keypad:
|
@irq_keypad:
|
||||||
jsr kp_read_on_irq
|
jsr kp::read_irq
|
||||||
bra @irq_return
|
bra @irq_return
|
||||||
@irq_spi_p:
|
@irq_spi_p:
|
||||||
jsr spi_p::read
|
jsr spi_p::read
|
||||||
@ -92,7 +95,7 @@ irq:
|
|||||||
; Reset sequence
|
; Reset sequence
|
||||||
;********************************************************************************
|
;********************************************************************************
|
||||||
reset:
|
reset:
|
||||||
jsr lcd_init
|
jsr lcd::init
|
||||||
|
|
||||||
; TODO debug stuff
|
; TODO debug stuff
|
||||||
stz IO2 + IO::DDRB
|
stz IO2 + IO::DDRB
|
||||||
@ -102,7 +105,7 @@ reset:
|
|||||||
DEBUG_LED_OFF 1
|
DEBUG_LED_OFF 1
|
||||||
|
|
||||||
|
|
||||||
jsr kp_init
|
jsr kp::init
|
||||||
|
|
||||||
|
|
||||||
; ; INIT DHT
|
; ; INIT DHT
|
||||||
@ -124,17 +127,17 @@ reset:
|
|||||||
Print message_menu
|
Print message_menu
|
||||||
; jsr rb_keypad_read
|
; jsr rb_keypad_read
|
||||||
@loop:
|
@loop:
|
||||||
lda _KP_DEBUG_VAL
|
lda kp::_DEBUG_VAL
|
||||||
beq @loop
|
beq @loop
|
||||||
; TODO debug
|
; TODO debug
|
||||||
sta 0
|
sta 0
|
||||||
stz _KP_DEBUG_VAL
|
stz kp::_DEBUG_VAL
|
||||||
lda 0
|
lda 0
|
||||||
; beq home
|
; beq home
|
||||||
cmp #'A'
|
cmp #'A'
|
||||||
jeq printer
|
jeq printer
|
||||||
cmp #'B'
|
cmp #'B'
|
||||||
jeq spi_menu::spi_menu
|
jeq spi_menu
|
||||||
cmp #'C'
|
cmp #'C'
|
||||||
jeq print_1
|
jeq print_1
|
||||||
cmp #'D'
|
cmp #'D'
|
||||||
@ -166,23 +169,23 @@ reset:
|
|||||||
DEBUG_LED_ON 1
|
DEBUG_LED_ON 1
|
||||||
jmp @loop
|
jmp @loop
|
||||||
@print_rb:
|
@print_rb:
|
||||||
jsr lcd_clear
|
jsr lcd::clear
|
||||||
Print str_io2
|
Print str_io2
|
||||||
lda IO2 + IO::RB
|
lda IO2 + IO::RB
|
||||||
jsr lcd_char
|
jsr lcd::print_char
|
||||||
lda #'''
|
lda #'''
|
||||||
jsr lcd_char
|
jsr lcd::print_char
|
||||||
jmp @loop
|
jmp @loop
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
print_1:
|
print_1:
|
||||||
jsr lcd_clear
|
jsr lcd::clear
|
||||||
PrintSlow message_1,10
|
PrintSlow message_1,10
|
||||||
jmp home
|
jmp home
|
||||||
|
|
||||||
print_2:
|
print_2:
|
||||||
jsr lcd_clear
|
jsr lcd::clear
|
||||||
PrintSlow message_2,10
|
PrintSlow message_2,10
|
||||||
jmp home
|
jmp home
|
||||||
|
|
||||||
|
260
programs/dht.s65
260
programs/dht.s65
@ -1,155 +1,155 @@
|
|||||||
;********************************************************************************
|
;;********************************************************************************
|
||||||
; @module SPI
|
;; @module SPI
|
||||||
; @type driver
|
;; @type driver
|
||||||
; @details
|
;; @details
|
||||||
; @depends IO-W65C22N
|
;; @depends IO-W65C22N
|
||||||
;********************************************************************************
|
;;********************************************************************************
|
||||||
|
|
||||||
;TODO EVERYTHING
|
;;TODO EVERYTHING
|
||||||
DHT_REQUEST_L = $00
|
;DHT_REQUEST_L = $00
|
||||||
DHT_REQUEST_H = %01010000 ; = 20480 PHI2 pulses = 20,5 ms at 1 MHz
|
;DHT_REQUEST_H = %01010000 ; = 20480 PHI2 pulses = 20,5 ms at 1 MHz
|
||||||
|
|
||||||
DHT_RECV_H = %10011100
|
;DHT_RECV_H = %10011100
|
||||||
DHT_RECV_L = %01000000 ; = 40000 PHI2 = 40ms
|
;DHT_RECV_L = %01000000 ; = 40000 PHI2 = 40ms
|
||||||
|
|
||||||
; Status Variables, Used to determine what is sent by temp module
|
;; Status Variables, Used to determine what is sent by temp module
|
||||||
DHT_STATUS = $400
|
;DHT_STATUS = $400
|
||||||
DHT_NONE = 0
|
;DHT_NONE = 0
|
||||||
DHT_WAIT_REQ = 1
|
;DHT_WAIT_REQ = 1
|
||||||
DHT_WAIT_RESP = 2
|
;DHT_WAIT_RESP = 2
|
||||||
DHT_RECV = 3
|
;DHT_RECV = 3
|
||||||
DHT_DONE = 4
|
;DHT_DONE = 4
|
||||||
|
|
||||||
DHT_BIT = $401
|
;DHT_BIT = $401
|
||||||
DHT_BIT_ROT = $402
|
;DHT_BIT_ROT = $402
|
||||||
|
|
||||||
|
|
||||||
DHT_VALUES = $405 ;
|
;DHT_VALUES = $405 ;
|
||||||
DHT_OFFSET = $403
|
;DHT_OFFSET = $403
|
||||||
DHT_OFF_RH_HIGH = 0 ; offsets to DHT_VALUES
|
;DHT_OFF_RH_HIGH = 0 ; offsets to DHT_VALUES
|
||||||
DHT_OFF_RH_LOW = 1
|
;DHT_OFF_RH_LOW = 1
|
||||||
DHT_OFF_T_HIGH = 2
|
;DHT_OFF_T_HIGH = 2
|
||||||
DHT_OFF_T_LOW = 3
|
;DHT_OFF_T_LOW = 3
|
||||||
DHT_OFF_CHECKSUM = 4
|
;DHT_OFF_CHECKSUM = 4
|
||||||
DHT_OFF_DONE = 5
|
;DHT_OFF_DONE = 5
|
||||||
|
|
||||||
|
|
||||||
message_dht: .asciiz "DHT-Request gesendet."
|
;message_dht: .asciiz "DHT-Request gesendet."
|
||||||
dht_wait:
|
;dht_wait:
|
||||||
ldx #$00
|
; ldx #$00
|
||||||
dht_wait_:
|
;dht_wait_:
|
||||||
lda message_dht,x
|
; lda message_dht,x
|
||||||
sta TO_PRINT,x
|
; sta TO_PRINT,x
|
||||||
inx
|
; inx
|
||||||
bne dht_wait_
|
; bne dht_wait_
|
||||||
jsr lcd_print_clear
|
; jsr lcd_print_clear
|
||||||
dht_wait_loop: ; check after every interrpt if dht program is done and then return home
|
;dht_wait_loop: ; check after every interrpt if dht program is done and then return home
|
||||||
lda #'.'
|
; lda #'.'
|
||||||
jsr _lcd_char
|
; jsr _lcd::print_char
|
||||||
wai
|
; wai
|
||||||
lda DHT_STATUS
|
; lda DHT_STATUS
|
||||||
cmp #DHT_DONE
|
; cmp #DHT_DONE
|
||||||
bne dht_wait_loop
|
; bne dht_wait_loop
|
||||||
|
|
||||||
dht_exit:
|
;dht_exit:
|
||||||
jsr kb_read
|
; jsr kb_read
|
||||||
cmp #'*'
|
; cmp #'*'
|
||||||
jeq home
|
; jeq home
|
||||||
bra dht_exit
|
; bra dht_exit
|
||||||
jmp return_home
|
; jmp return_home
|
||||||
|
|
||||||
dht_request: ; send request to sensor
|
;dht_request: ; send request to sensor
|
||||||
sei
|
; sei
|
||||||
|
|
||||||
lda #%00000001 ; set PA1-0 to output 0
|
; lda #%00000001 ; set PA1-0 to output 0
|
||||||
ora IO2 + IO_DDRA
|
; ora IO2 + IO_DDRA
|
||||||
sta IO2 + IO_DDRA
|
; sta IO2 + IO_DDRA
|
||||||
lda #(LCD_CLEAR | $00)
|
; lda #(LCD_CLEAR | $00)
|
||||||
sta IO2 + IO_RA
|
; sta IO2 + IO_RA
|
||||||
|
|
||||||
; start timer
|
; ; start timer
|
||||||
lda #DHT_REQUEST_L
|
; lda #DHT_REQUEST_L
|
||||||
sta IO2 + IO_T1CL
|
; sta IO2 + IO_T1CL
|
||||||
lda #DHT_REQUEST_H
|
; lda #DHT_REQUEST_H
|
||||||
sta IO2 + IO_T1CH
|
; sta IO2 + IO_T1CH
|
||||||
|
|
||||||
lda #DHT_WAIT_REQ
|
; lda #DHT_WAIT_REQ
|
||||||
sta DHT_STATUS
|
; sta DHT_STATUS
|
||||||
|
|
||||||
cli
|
; cli
|
||||||
jmp dht_wait
|
; jmp dht_wait
|
||||||
|
|
||||||
|
|
||||||
dht_request_end:
|
;dht_request_end:
|
||||||
lda #%10000010
|
; lda #%10000010
|
||||||
sta IO2 + IO_IER ; enable Interrupt for CA1
|
; sta IO2 + IO_IER ; enable Interrupt for CA1
|
||||||
lda #%11111110
|
; lda #%11111110
|
||||||
and IO2 + IO_DDRA
|
; and IO2 + IO_DDRA
|
||||||
sta IO2 + IO_DDRA ; set PA1-0 to input
|
; sta IO2 + IO_DDRA ; set PA1-0 to input
|
||||||
|
|
||||||
lda #DHT_WAIT_RESP
|
; lda #DHT_WAIT_RESP
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dht_response: ; receive response from sensor
|
;dht_response: ; receive response from sensor
|
||||||
lda #DHT_RECV
|
; lda #DHT_RECV
|
||||||
sta DHT_STATUS
|
; sta DHT_STATUS
|
||||||
stz DHT_OFFSET
|
; stz DHT_OFFSET
|
||||||
lda #7
|
; lda #7
|
||||||
sta DHT_BIT
|
; sta DHT_BIT
|
||||||
|
|
||||||
dht_recv:
|
;dht_recv:
|
||||||
; start timer
|
; ; start timer
|
||||||
lda #DHT_RECV_L
|
; lda #DHT_RECV_L
|
||||||
sta IO2 + IO_T1CL
|
; sta IO2 + IO_T1CL
|
||||||
lda #DHT_RECV_H
|
; lda #DHT_RECV_H
|
||||||
sta IO2 + IO_T1CH
|
; sta IO2 + IO_T1CH
|
||||||
rts
|
; rts
|
||||||
|
|
||||||
dht_recv_read:
|
;dht_recv_read:
|
||||||
; read PA2
|
; ; read PA2
|
||||||
lda IO2 + IO_RA
|
; lda IO2 + IO_RA
|
||||||
and #%00000001
|
; and #%00000001
|
||||||
ldx DHT_BIT
|
; ldx DHT_BIT
|
||||||
beq dht_recv_end
|
; beq dht_recv_end
|
||||||
dht_recv_rot:
|
;dht_recv_rot:
|
||||||
rol
|
; rol
|
||||||
dex
|
; dex
|
||||||
bne dht_recv_rot
|
; bne dht_recv_rot
|
||||||
dht_recv_end:
|
;dht_recv_end:
|
||||||
ldy DHT_OFFSET
|
; ldy DHT_OFFSET
|
||||||
ora DHT_VALUES,y
|
; ora DHT_VALUES,y
|
||||||
sta DHT_VALUES,y
|
; sta DHT_VALUES,y
|
||||||
; determine if 8 bits are done
|
; ; determine if 8 bits are done
|
||||||
ldx DHT_BIT
|
; ldx DHT_BIT
|
||||||
beq dht_recv_next
|
; beq dht_recv_next
|
||||||
rts
|
; rts
|
||||||
dht_recv_next:
|
;dht_recv_next:
|
||||||
lda #7
|
; lda #7
|
||||||
sta DHT_BIT
|
; sta DHT_BIT
|
||||||
inc DHT_OFFSET
|
; inc DHT_OFFSET
|
||||||
cmp DHT_OFF_DONE
|
; cmp DHT_OFF_DONE
|
||||||
beq dht_display
|
; beq dht_display
|
||||||
rts
|
; rts
|
||||||
|
|
||||||
dht_display:
|
;dht_display:
|
||||||
ldx #0
|
; ldx #0
|
||||||
dht_display_:
|
;dht_display_:
|
||||||
lda DHT_VALUES,x
|
; lda DHT_VALUES,x
|
||||||
sta TO_PRINT,x
|
; sta TO_PRINT,x
|
||||||
inx
|
; inx
|
||||||
cpx #5
|
; cpx #5
|
||||||
bne dht_display_
|
; bne dht_display_
|
||||||
jsr lcd_print_clear
|
; jsr lcd_print_clear
|
||||||
rts
|
; rts
|
||||||
|
|
||||||
dht_irq:
|
;dht_irq:
|
||||||
lda DHT_STATUS
|
; lda DHT_STATUS
|
||||||
cmp #DHT_WAIT_REQ
|
; cmp #DHT_WAIT_REQ
|
||||||
beq dht_request_end
|
; beq dht_request_end
|
||||||
cmp #DHT_WAIT_RESP
|
; cmp #DHT_WAIT_RESP
|
||||||
beq dht_response
|
; beq dht_response
|
||||||
cmp #DHT_RECV
|
; cmp #DHT_RECV
|
||||||
beq dht_recv
|
; beq dht_recv
|
||||||
rts
|
; rts
|
||||||
|
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
.ifndef INCLUDE_MEMCOPY
|
.ifndef INCLUDE_MEMCOPY
|
||||||
INCLUDE_MEMCOPY = 1
|
INCLUDE_MEMCOPY = 1
|
||||||
|
|
||||||
|
.include "system.h65"
|
||||||
|
|
||||||
|
.code
|
||||||
;********************************************************************************
|
;********************************************************************************
|
||||||
; @function Copy a block of memory to a different address
|
; @function Copy a block of memory to a different address
|
||||||
; @param ARG0-1: Source address
|
; @param ARG0-1: Source address
|
||||||
@ -9,14 +11,15 @@ INCLUDE_MEMCOPY = 1
|
|||||||
; @param y: Number of bytes to copy
|
; @param y: Number of bytes to copy
|
||||||
;********************************************************************************
|
;********************************************************************************
|
||||||
.proc memcopy
|
.proc memcopy
|
||||||
cpy
|
cpy #0
|
||||||
loop:
|
@loop:
|
||||||
beq @loop_end
|
beq @loop_end
|
||||||
lda (ARG0),y
|
lda (ARG0),y
|
||||||
sta (ARG2),y
|
sta (ARG2),y
|
||||||
dey
|
dey
|
||||||
bra @loop
|
bra @loop
|
||||||
loop_end:
|
@loop_end:
|
||||||
rts
|
rts
|
||||||
|
.endproc
|
||||||
.endif ; guard
|
.endif ; guard
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
|
|
||||||
.ifndef INCLUDE_PRINT_SLOW
|
.ifndef INCLUDE_PRINT_SLOW
|
||||||
INCLUDE_PRINT_SLOW = 1
|
INCLUDE_PRINT_SLOW = 1
|
||||||
|
|
||||||
.include "programs/sleep.s65"
|
.include "system.h65"
|
||||||
.include "system/lcd.s65"
|
.include "sleep.s65"
|
||||||
|
.include "lcd.h65"
|
||||||
|
|
||||||
|
.code
|
||||||
;********************************************************************************
|
;********************************************************************************
|
||||||
; @function Print a null-terminated string
|
; @function Print a null-terminated string
|
||||||
; @param ARG0-1: Address of the string to print
|
; @param ARG0-1: Address of the string to print
|
||||||
@ -19,7 +19,7 @@ INCLUDE_PRINT_SLOW = 1
|
|||||||
phx
|
phx
|
||||||
jsr sleep
|
jsr sleep
|
||||||
plx
|
plx
|
||||||
jsr lcd_char
|
jsr lcd::print_char
|
||||||
iny
|
iny
|
||||||
bra @print_loop
|
bra @print_loop
|
||||||
@print_end:
|
@print_end:
|
||||||
@ -32,7 +32,7 @@ INCLUDE_PRINT_SLOW = 1
|
|||||||
; @param time_cs: time to sleep in centiseconds
|
; @param time_cs: time to sleep in centiseconds
|
||||||
;********************************************************************************
|
;********************************************************************************
|
||||||
.macro PrintSlow message,time_cs
|
.macro PrintSlow message,time_cs
|
||||||
jsr lcd_clear
|
jsr lcd::clear
|
||||||
lda #<message
|
lda #<message
|
||||||
sta ARG0
|
sta ARG0
|
||||||
lda #>message
|
lda #>message
|
||||||
|
10
programs/printer.h65
Normal file
10
programs/printer.h65
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
;********************************************************************************
|
||||||
|
; Printing Program
|
||||||
|
;********************************************************************************
|
||||||
|
.ifndef INCLUDE_PRINTER
|
||||||
|
INCLUDE_PRINTER = 1
|
||||||
|
|
||||||
|
.global printer
|
||||||
|
.import home:absolute
|
||||||
|
|
||||||
|
.endif ; guard
|
@ -1,16 +1,15 @@
|
|||||||
;********************************************************************************
|
.include "printer.h65"
|
||||||
; Printing Program
|
.include "lcd.h65"
|
||||||
;********************************************************************************
|
.include "keypad.h65"
|
||||||
.ifndef INCLUDE_PRINTER
|
|
||||||
INCLUDE_PRINTER = 1
|
|
||||||
.code
|
.code
|
||||||
printer:
|
.proc printer
|
||||||
jsr lcd_clear
|
jsr lcd::clear
|
||||||
@printer_loop:
|
@printer_loop:
|
||||||
jsr rb_keypad_read
|
jsr kp::read
|
||||||
beq @printer_loop
|
beq @printer_loop
|
||||||
cmp #'*'
|
cmp #'*'
|
||||||
jeq home
|
jeq home
|
||||||
jsr lcd_char
|
jsr lcd::print_char
|
||||||
bra @printer_loop
|
bra @printer_loop
|
||||||
.endif ; guard
|
.endproc
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
.ifndef INCLUDE_SLEEP
|
.ifndef INCLUDE_SLEEP
|
||||||
INCLUDE_SLEEP = 1
|
INCLUDE_SLEEP = 1
|
||||||
|
.include "system.h65"
|
||||||
.code
|
.code
|
||||||
;********************************************************************************
|
;********************************************************************************
|
||||||
; @macro Sleep
|
; @macro Sleep
|
||||||
@ -20,10 +21,10 @@ INCLUDE_SLEEP = 1
|
|||||||
; @details
|
; @details
|
||||||
; Interrupts might change the actual time to finish
|
; Interrupts might change the actual time to finish
|
||||||
; To be exact, time_cs is in units of 0.010244s
|
; To be exact, time_cs is in units of 0.010244s
|
||||||
; @modifies: ARG2
|
; @modifies: ARG15
|
||||||
;********************************************************************************
|
;********************************************************************************
|
||||||
.proc sleep
|
.proc sleep
|
||||||
_VAR_1 = ARG2
|
_VAR_1 = ARG15
|
||||||
stz _VAR_1
|
stz _VAR_1
|
||||||
@loop:
|
@loop:
|
||||||
.repeat 17
|
.repeat 17
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
.include "system/spi.s65"
|
.include "spi.h65"
|
||||||
.include "util/string.s65"
|
.include "string.h65"
|
||||||
.ifndef INCLUDE_SPI_MENU
|
.include "keypad.h65"
|
||||||
INCLUDE_SPI_MENU = 1
|
.include "lcd.h65"
|
||||||
|
.import home:absolute
|
||||||
|
.import SPI_IO
|
||||||
|
|
||||||
.scope spi_menu
|
.export spi_menu
|
||||||
.bss
|
.bss
|
||||||
trans_bytes: .res 1
|
trans_bytes: .res 1
|
||||||
trans_pages: .res 1
|
trans_pages: .res 1
|
||||||
@ -17,12 +19,12 @@ status_str: .res 17 ; 16 + null
|
|||||||
lda #'X'
|
lda #'X'
|
||||||
sta status
|
sta status
|
||||||
@print_menu:
|
@print_menu:
|
||||||
jsr lcd_clear
|
jsr lcd::clear
|
||||||
Print MENU
|
Print MENU
|
||||||
@print_status:
|
@print_status:
|
||||||
Strf FMT_STATUS,status_str,trans_pages,trans_bytes,status
|
Strf FMT_STATUS,status_str,trans_pages,trans_bytes,status
|
||||||
lda #(LCD_CMD_SET_ADDRESS | LCD_LINE4)
|
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE4)
|
||||||
jsr _lcd_cmd
|
jsr lcd::_cmd
|
||||||
Print status_str
|
Print status_str
|
||||||
@loop:
|
@loop:
|
||||||
; check if a byte has been transferred
|
; check if a byte has been transferred
|
||||||
@ -43,11 +45,11 @@ status_str: .res 17 ; 16 + null
|
|||||||
bra @print_status
|
bra @print_status
|
||||||
|
|
||||||
@read_keypad:
|
@read_keypad:
|
||||||
lda _KP_DEBUG_VAL
|
lda kp::_DEBUG_VAL
|
||||||
beq @loop
|
beq @loop
|
||||||
; TODO debug
|
; TODO debug
|
||||||
sta 0
|
sta 0
|
||||||
stz _KP_DEBUG_VAL
|
stz kp::_DEBUG_VAL
|
||||||
lda 0
|
lda 0
|
||||||
cmp #'*'
|
cmp #'*'
|
||||||
beq @return_home
|
beq @return_home
|
||||||
@ -70,9 +72,9 @@ status_str: .res 17 ; 16 + null
|
|||||||
jmp @print_menu
|
jmp @print_menu
|
||||||
@spi_jump:
|
@spi_jump:
|
||||||
jsr spi_p::end
|
jsr spi_p::end
|
||||||
jsr lcd_clear
|
jsr lcd::clear
|
||||||
Print START
|
Print START
|
||||||
jmp spi_p::SPI_CODE_START
|
jmp spi_p::CODE_START
|
||||||
@return_home:
|
@return_home:
|
||||||
jsr spi_p::end
|
jsr spi_p::end
|
||||||
jmp home
|
jmp home
|
||||||
@ -87,6 +89,3 @@ MENU:
|
|||||||
FMT_STATUS: .asciiz "%x%xb Status:%x"
|
FMT_STATUS: .asciiz "%x%xb Status:%x"
|
||||||
BEGIN: .asciiz "---BEGIN SPI---"
|
BEGIN: .asciiz "---BEGIN SPI---"
|
||||||
START: .asciiz "---START SPI---"
|
START: .asciiz "---START SPI---"
|
||||||
|
|
||||||
.endscope
|
|
||||||
.endif ; guard
|
|
||||||
|
149
spicode.s65
Normal file
149
spicode.s65
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
.include "system.h65"
|
||||||
|
.include "lcd.h65"
|
||||||
|
.include "math.h65"
|
||||||
|
.import home:absolute
|
||||||
|
.segment "SPI"
|
||||||
|
.export CODE_START
|
||||||
|
|
||||||
|
Export
|
||||||
|
CODE_START:
|
||||||
|
lda '$'
|
||||||
|
jsr lcd::print_char
|
||||||
|
lda #<TEST_FMT
|
||||||
|
sta ARG0
|
||||||
|
lda #>TEST_FMT
|
||||||
|
sta ARG1
|
||||||
|
lda #<TEST_OUT
|
||||||
|
sta ARG2
|
||||||
|
lda #>TEST_OUT
|
||||||
|
sta ARG3
|
||||||
|
lda #$a9
|
||||||
|
sta ARG4
|
||||||
|
lda #$3c
|
||||||
|
sta ARG5
|
||||||
|
lda #$10
|
||||||
|
sta ARG6
|
||||||
|
jsr strf
|
||||||
|
Print TEST_OUT
|
||||||
|
@spiloop:
|
||||||
|
bbs4 ASDA,dasdZQ
|
||||||
|
lda IO1 + IO::RA
|
||||||
|
lda IO2 + IO::RA
|
||||||
|
jeq @spiloop
|
||||||
|
bge @spiloop
|
||||||
|
nop
|
||||||
|
bra @spiloop
|
||||||
|
bro @spiloop
|
||||||
|
jmp home
|
||||||
|
lda €asdaasd
|
||||||
|
lda €$ff
|
||||||
|
lds €asda
|
||||||
|
|
||||||
|
lds #($ff | asd)
|
||||||
|
lda #'c'
|
||||||
|
lda #(jk:)
|
||||||
|
|
||||||
|
|
||||||
|
; TODO allocate zp memory
|
||||||
|
fmt_idx = $30
|
||||||
|
out_idx = $31
|
||||||
|
;********************************************************************************
|
||||||
|
; @function Format a string
|
||||||
|
; @details
|
||||||
|
; If there is no value to be read, the Pz will be set
|
||||||
|
; Formats:
|
||||||
|
; - u: unsigned decimal integer (1 byte)
|
||||||
|
; - U: unsigned decimal integer (2 bytes)
|
||||||
|
; @param ARG0-1: Format string address
|
||||||
|
; @param ARG2-3: Output string address
|
||||||
|
; @param ARG4+: Additional parameters
|
||||||
|
; @returns
|
||||||
|
; @modifies: A, Y
|
||||||
|
;********************************************************************************
|
||||||
|
.proc strf
|
||||||
|
stz out_idx
|
||||||
|
stz fmt_idx
|
||||||
|
ldy #0 ; position in string
|
||||||
|
ldx #0 ; index of format args
|
||||||
|
@loop:
|
||||||
|
ldy fmt_idx
|
||||||
|
lda (ARG0),y
|
||||||
|
beq @null
|
||||||
|
cmp #'%'
|
||||||
|
beq @percent
|
||||||
|
@normal_char: ; store A in output string
|
||||||
|
ldy out_idx
|
||||||
|
sta (ARG2),y
|
||||||
|
inc fmt_idx
|
||||||
|
inc out_idx
|
||||||
|
beq @out_overflow
|
||||||
|
bra @loop
|
||||||
|
@percent: ; check for format in next position
|
||||||
|
iny
|
||||||
|
sty fmt_idx
|
||||||
|
lda (ARG0),y
|
||||||
|
beq @null
|
||||||
|
; formats
|
||||||
|
cmp #'x'
|
||||||
|
beq @format_hex1
|
||||||
|
bra @normal_char
|
||||||
|
@format_hex1: ; 1 byte hex -> 2 chars
|
||||||
|
lda ARG4,x
|
||||||
|
phx
|
||||||
|
jsr int8_to_hex_str
|
||||||
|
ldy out_idx
|
||||||
|
sta (ARG2),y ; most sig digit
|
||||||
|
iny
|
||||||
|
beq @out_overflow
|
||||||
|
txa
|
||||||
|
sta (ARG2),y ; least sig digit
|
||||||
|
iny
|
||||||
|
beq @out_overflow
|
||||||
|
sty out_idx
|
||||||
|
plx
|
||||||
|
inx ; 1 byte of args handeled
|
||||||
|
; bra @format_return
|
||||||
|
@format_return: ; increment fmt_idx to swallow the formating char
|
||||||
|
inc fmt_idx
|
||||||
|
bra @loop
|
||||||
|
@out_overflow: ; store 0 in last position
|
||||||
|
ldy #$ff
|
||||||
|
sty out_idx
|
||||||
|
@store_null:
|
||||||
|
lda #0
|
||||||
|
@null: ; store and return
|
||||||
|
ldy out_idx
|
||||||
|
sta (ARG2),y
|
||||||
|
@rts:
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
|
;********************************************************************************
|
||||||
|
; @function Convert a 1 byte number into two hex characters
|
||||||
|
; @param A: Number to convert
|
||||||
|
; @returns A: Most significant digit
|
||||||
|
; @returns X: Least significant digit
|
||||||
|
; @modifies X,Y,A
|
||||||
|
;********************************************************************************
|
||||||
|
.proc int8_to_hex_str
|
||||||
|
pha
|
||||||
|
and #%00001111
|
||||||
|
tay
|
||||||
|
ldx HEX_CHARS,y
|
||||||
|
pla
|
||||||
|
div A,16
|
||||||
|
and #%00001111
|
||||||
|
tay
|
||||||
|
lda HEX_CHARS,y
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
HEX_CHARS: .byte "0123456789ABCDEF"
|
||||||
|
|
||||||
|
TEST_FMT: .asciiz "%x -> %x -> %x:)"
|
||||||
|
TEST_OUT: .asciiz "TESTOUT"
|
||||||
|
|
@ -77,7 +77,6 @@ RB_LENGTH = RBUF_MEM_END - RBUF_MEM_START - 2
|
|||||||
; @param A: value to store
|
; @param A: value to store
|
||||||
; @modifies: X
|
; @modifies: X
|
||||||
;********************************************************************************
|
;********************************************************************************
|
||||||
;TODO increment read when write reaches it
|
|
||||||
.ident(.concat(_RBUF_NAME, "_write")):
|
.ident(.concat(_RBUF_NAME, "_write")):
|
||||||
.scope
|
.scope
|
||||||
; lda kp_VALUES, x ; load the char in a
|
; lda kp_VALUES, x ; load the char in a
|
29
system/keypad.h65
Normal file
29
system/keypad.h65
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
;********************************************************************************
|
||||||
|
; @module keypad4x4
|
||||||
|
; @type driver
|
||||||
|
; @device 4x4 Matrix Keypad
|
||||||
|
; @details
|
||||||
|
; The LCD must be connected to a W65C22N Interface Chip:
|
||||||
|
; - IO.RA0-7 ->
|
||||||
|
; @requires KP_IO: Base Address of IO Chip
|
||||||
|
; @depends IO-W65C22N
|
||||||
|
;********************************************************************************
|
||||||
|
.ifndef INCLUDE_KEYPAD
|
||||||
|
INCLUDE_KEYPAD = 1
|
||||||
|
.include "system.h65"
|
||||||
|
|
||||||
|
.scope kp
|
||||||
|
KP_IO = IO2
|
||||||
|
; .import KP_IO
|
||||||
|
; .ifndef KP_IO
|
||||||
|
; .fatal "KP_IO is not defined: set it to the base address of the IO chip of the Keypad"
|
||||||
|
; .endif
|
||||||
|
|
||||||
|
Import kp, init, read_irq, read
|
||||||
|
ImportZp kp,_DEBUG_VAL
|
||||||
|
|
||||||
|
BUF_SIZE = 10
|
||||||
|
|
||||||
|
.endscope
|
||||||
|
.endif ; guard
|
||||||
|
|
@ -1,57 +1,45 @@
|
|||||||
;********************************************************************************
|
.include "keypad.h65"
|
||||||
; @module keypad4x4
|
|
||||||
; @type driver
|
|
||||||
; @device 4x4 Matrix Keypad
|
|
||||||
; @details
|
|
||||||
; The LCD must be connected to a W65C22N Interface Chip:
|
|
||||||
; - IO.RA0-7 ->
|
|
||||||
; @requires KP_IO: Base Address of IO Chip
|
|
||||||
; @depends IO-W65C22N
|
|
||||||
;********************************************************************************
|
|
||||||
|
|
||||||
|
Export kp, init, read_irq, read
|
||||||
.ifndef INCLUDE_KEYPAD
|
ExportZp kp, _DEBUG_VAL
|
||||||
INCLUDE_KEYPAD = 1
|
|
||||||
.ifndef KP_IO
|
|
||||||
.fatal "KP_IO is not defined: set it to the base address of the IO chip of the Keypad"
|
|
||||||
.endif
|
|
||||||
|
|
||||||
.zeropage
|
.zeropage
|
||||||
_KP_COLUMN: .res 1 ; for storing stuff
|
_COLUMN: .res 1 ; for storing stuff
|
||||||
_KP_DEBUG_VAL: .res 1 ; for storing the last char DEBUG
|
_DEBUG_VAL: .res 1 ; for storing the last char DEBUG
|
||||||
|
|
||||||
.bss ; reserve space or ringbuffer
|
.bss ; reserve space or ringbuffer
|
||||||
KP_BUF_SIZE = 10
|
RBUF_MEM_START: .res kp::BUF_SIZE
|
||||||
RBUF_MEM_START: .res KP_BUF_SIZE
|
RBUF_MEM_END = RBUF_MEM_START + kp::BUF_SIZE - 1
|
||||||
RBUF_MEM_END = RBUF_MEM_START + KP_BUF_SIZE - 1
|
|
||||||
.define RBUF_NAME "keypad"
|
.define RBUF_NAME "keypad"
|
||||||
.include "buffer.s65"
|
.include "buffer.h65"
|
||||||
|
|
||||||
.code
|
.code
|
||||||
.proc kp_init
|
.proc init
|
||||||
; todo remove later and test
|
; todo remove later and test
|
||||||
lda #$ff
|
lda #$ff
|
||||||
sta KP_IO+IO::DDRA
|
sta kp::KP_IO+IO::DDRA
|
||||||
stz KP_IO+IO::RA
|
stz kp::KP_IO+IO::RA
|
||||||
|
|
||||||
; INIT KEYPAD
|
; INIT KEYPAD
|
||||||
; todo: use masks
|
; todo: use masks
|
||||||
lda #%11110000; KP_IO+IO::RA 0-3 output
|
lda #%11110000; kp::KP_IO+IO::RA 0-3 output
|
||||||
sta KP_IO+IO::DDRA
|
sta kp::KP_IO+IO::DDRA
|
||||||
; output 0, key press will pull input pin low
|
; output 0, key press will pull input pin low
|
||||||
stz KP_IO+IO::RA
|
stz kp::KP_IO+IO::RA
|
||||||
stz KP_IO+IO::ACR
|
stz kp::KP_IO+IO::ACR
|
||||||
|
|
||||||
; lda #%00010000 ; set CA1 to interrupt on pos. edge
|
; lda #%00010000 ; set CA1 to interrupt on pos. edge
|
||||||
; todo: use masks
|
; todo: use masks
|
||||||
lda #IO::PCR::CA1_IP_AE
|
lda #IO::PCR::CA1_IP_AE
|
||||||
sta KP_IO+IO::PCR
|
sta kp::KP_IO+IO::PCR
|
||||||
jsr rb_keypad_init ; init keybuffer
|
jsr rb_keypad_init ; init keybuffer
|
||||||
lda #(IO::IRQ::IRQ | IO::IRQ::CA1) ; enable interrupt for CA1 on KP_IO
|
lda #(IO::IRQ::IRQ | IO::IRQ::CA1) ; enable interrupt for CA1 on kp::KP_IO
|
||||||
sta KP_IO+IO::IER
|
sta kp::KP_IO+IO::IER
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
|
read = rb_keypad_read
|
||||||
|
|
||||||
;********************************************************************************
|
;********************************************************************************
|
||||||
; @function Read which key is pressed on the keypad
|
; @function Read which key is pressed on the keypad
|
||||||
; @details
|
; @details
|
||||||
@ -59,7 +47,7 @@ RBUF_MEM_END = RBUF_MEM_START + KP_BUF_SIZE - 1
|
|||||||
; The value stored in the keybuffer is the offset which must be added to
|
; The value stored in the keybuffer is the offset which must be added to
|
||||||
; kp_VALUES to retrieve the key that was pressed
|
; kp_VALUES to retrieve the key that was pressed
|
||||||
;********************************************************************************
|
;********************************************************************************
|
||||||
.proc kp_read_on_irq
|
.proc read_irq
|
||||||
; test each "row" and check which column is 1
|
; test each "row" and check which column is 1
|
||||||
; TODO dont check every column if the value has been found
|
; TODO dont check every column if the value has been found
|
||||||
lda #%11100000
|
lda #%11100000
|
||||||
@ -74,31 +62,31 @@ RBUF_MEM_END = RBUF_MEM_START + KP_BUF_SIZE - 1
|
|||||||
lda #%01110000
|
lda #%01110000
|
||||||
ldx #$0c
|
ldx #$0c
|
||||||
jsr @kp_read_column
|
jsr @kp_read_column
|
||||||
stz KP_IO+IO::RA
|
stz kp::KP_IO+IO::RA
|
||||||
lda KP_IO+IO::RA ; clear interrupt flag again beceause it might be set again through the above tests
|
lda kp::KP_IO+IO::RA ; clear interrupt flag again beceause it might be set again through the above tests
|
||||||
rts
|
rts
|
||||||
@kp_read_column:
|
@kp_read_column:
|
||||||
sta KP_IO+IO::RA
|
sta kp::KP_IO+IO::RA
|
||||||
lda KP_IO+IO::RA
|
lda kp::KP_IO+IO::RA
|
||||||
sta _KP_COLUMN ; store result in zeropage so that bbr can be used
|
sta _COLUMN ; store result in zeropage so that bbr can be used
|
||||||
bbr0 _KP_COLUMN,@kp_write ; row 1
|
bbr0 _COLUMN,@kp_write ; row 1
|
||||||
inx
|
inx
|
||||||
bbr1 _KP_COLUMN,@kp_write ; row 3
|
bbr1 _COLUMN,@kp_write ; row 3
|
||||||
inx
|
inx
|
||||||
bbr2 _KP_COLUMN,@kp_write ; row 2
|
bbr2 _COLUMN,@kp_write ; row 2
|
||||||
inx
|
inx
|
||||||
bbr3 _KP_COLUMN,@kp_write ; row 4
|
bbr3 _COLUMN,@kp_write ; row 4
|
||||||
rts
|
rts
|
||||||
@kp_write:
|
@kp_write:
|
||||||
lda _KP_VALUES,x
|
lda VALUES,x
|
||||||
; TODO use ringbuffer
|
; TODO use ringbuffer
|
||||||
sta _KP_DEBUG_VAL
|
sta _DEBUG_VAL
|
||||||
jsr rb_keypad_write
|
jsr rb_keypad_write
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
.rodata
|
.rodata
|
||||||
_KP_VALUES:
|
VALUES:
|
||||||
.byte "174*"
|
.byte "174*"
|
||||||
.byte "2850"
|
.byte "2850"
|
||||||
.byte "396#"
|
.byte "396#"
|
||||||
@ -108,4 +96,3 @@ _KP_VALUES:
|
|||||||
; row 2 = PA2
|
; row 2 = PA2
|
||||||
; row 3 = PA1
|
; row 3 = PA1
|
||||||
; row 4 = PA3
|
; row 4 = PA3
|
||||||
.endif
|
|
||||||
|
60
system/lcd.h65
Normal file
60
system/lcd.h65
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
;********************************************************************************
|
||||||
|
; @module LCD-W164B
|
||||||
|
; @type driver
|
||||||
|
; @device ELECTRONIC ASSEMBLY - W164B-NLW
|
||||||
|
; @details
|
||||||
|
; The LCD must be connected to a W65C22N Interface Chip:
|
||||||
|
; - IO.RB0-7 -> LCD.D0-7 data lines
|
||||||
|
; - IO.RA5 -> LCD.RS register select
|
||||||
|
; - IO.RA6 -> LCD.R/W read/write
|
||||||
|
; - IO.RA7 -> LCD.E enable
|
||||||
|
;
|
||||||
|
; @requires IO: Base Address of IO Chip
|
||||||
|
; @optparam MEM: Memory address for a runtime variable. Default = $300
|
||||||
|
; @depends IO-W65C22N
|
||||||
|
;********************************************************************************
|
||||||
|
.ifndef INCLUDE_LCD
|
||||||
|
INCLUDE_LCD = 1
|
||||||
|
|
||||||
|
.include "system/system.h65"
|
||||||
|
|
||||||
|
.scope lcd
|
||||||
|
LCD_IO = IO1
|
||||||
|
Import lcd,init,clear,print,print_char,_cmd
|
||||||
|
|
||||||
|
;********************************************************************************
|
||||||
|
; @macro Print a null-terminated string
|
||||||
|
; @param message: Address of the message
|
||||||
|
;********************************************************************************
|
||||||
|
.macro Print message
|
||||||
|
jsr lcd::clear
|
||||||
|
lda #<message
|
||||||
|
sta ARG0
|
||||||
|
lda #>message
|
||||||
|
sta ARG1
|
||||||
|
jsr lcd::print
|
||||||
|
.endmacro
|
||||||
|
|
||||||
|
; PIN MASKS
|
||||||
|
E = %10000000
|
||||||
|
RW = %01000000
|
||||||
|
RS = %00100000
|
||||||
|
|
||||||
|
; LCD Instructions (see datasheet for more)
|
||||||
|
CMD_CLEAR = %00000001 ; clear display
|
||||||
|
CMD_ENTRY_MODE = %00000110 ; auto-shift cursor
|
||||||
|
CMD_DISPLAY_ON = %00001111 ; everything on, with blinking cursor
|
||||||
|
CMD_FUNCTION_SET = %00111000 ; 8-bit, 4 lines, 5x7 font
|
||||||
|
CMD_SET_ADDRESS = %10000000 ; or with the address
|
||||||
|
; LCD Constants
|
||||||
|
LINE1 = $00
|
||||||
|
LINE2 = $40
|
||||||
|
LINE3 = $10
|
||||||
|
LINE4 = $50
|
||||||
|
|
||||||
|
CLEAR = %00000000
|
||||||
|
|
||||||
|
.ifndef KEEPSCOPE
|
||||||
|
.endscope
|
||||||
|
.endif
|
||||||
|
.endif ; guard
|
315
system/lcd.s65
315
system/lcd.s65
@ -1,233 +1,214 @@
|
|||||||
;********************************************************************************
|
.include "system/lcd.h65"
|
||||||
; @module LCD-W164B
|
|
||||||
; @type driver
|
|
||||||
; @device ELECTRONIC ASSEMBLY - W164B-NLW
|
|
||||||
; @details
|
|
||||||
; The LCD must be connected to a W65C22N Interface Chip:
|
|
||||||
; - IO.RB0-7 -> LCD.D0-7 data lines
|
|
||||||
; - IO.RA5 -> LCD.RS register select
|
|
||||||
; - IO.RA6 -> LCD.R/W read/write
|
|
||||||
; - IO.RA7 -> LCD.E enable
|
|
||||||
;
|
|
||||||
; @requires LCD_IO: Base Address of IO Chip
|
|
||||||
; @optparam LCD_MEM: Memory address for a runtime variable. Default = $300
|
|
||||||
; @depends IO-W65C22N
|
|
||||||
;********************************************************************************
|
|
||||||
.ifndef INCLUDE_LCD
|
|
||||||
INCLUDE_LCD = 1
|
|
||||||
|
|
||||||
.ifndef LCD_IO
|
.ifndef lcd::LCD_IO
|
||||||
.fatal "LCD_IO is not defined: set it to the base address of the IO chip of the LCD"
|
.fatal "lcd::LCD_IO is not defined: set it to the base address of the IO chip of the LCD"
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.ifndef INCLUDE_IOW65C22
|
|
||||||
.error "IO-W65C22 module is not included"
|
|
||||||
.endif
|
|
||||||
|
|
||||||
.include "utility.h65"
|
|
||||||
|
|
||||||
|
Export lcd,init,clear,print,print_char,set_position
|
||||||
|
|
||||||
; RAM VARIABLES
|
; RAM VARIABLES
|
||||||
.ifndef LCD_MEM
|
.bss
|
||||||
LCD_MEM = $300
|
charcount: .res 1
|
||||||
.endif
|
|
||||||
LCD_CHARCOUNT = LCD_MEM
|
|
||||||
|
|
||||||
; PIN MASKS
|
.code
|
||||||
LCD_E = %10000000
|
;;********************************************************************************
|
||||||
LCD_RW = %01000000
|
;; @function Initialize the lcd module
|
||||||
LCD_RS = %00100000
|
;; @details call before doing anything else
|
||||||
; .local LCD_E,LCD_RW,LCD_RS
|
;; @modifies A
|
||||||
|
;;********************************************************************************
|
||||||
; LCD Instructions (see datasheet for more)
|
.proc init
|
||||||
LCD_CMD_CLEAR = %00000001 ; clear display
|
|
||||||
LCD_CMD_ENTRY_MODE = %00000110 ; auto-shift cursor
|
|
||||||
LCD_CMD_DISPLAY_ON = %00001111 ; everything on, with blinking cursor
|
|
||||||
LCD_CMD_FUNCTION_SET = %00111000 ; 8-bit, 4 lines, 5x7 font
|
|
||||||
LCD_CMD_SET_ADDRESS = %10000000 ; or with the address
|
|
||||||
; LCD Constants
|
|
||||||
LCD_LINE1 = $00
|
|
||||||
LCD_LINE2 = $40
|
|
||||||
LCD_LINE3 = $10
|
|
||||||
LCD_LINE4 = $50
|
|
||||||
|
|
||||||
LCD_CLEAR = %00000000
|
|
||||||
|
|
||||||
|
|
||||||
;********************************************************************************
|
|
||||||
; @function Initialize the lcd module
|
|
||||||
; @details call before doing anything else
|
|
||||||
;********************************************************************************
|
|
||||||
.proc lcd_init
|
|
||||||
; init IO
|
; init IO
|
||||||
lda #$ff ; RB 0-7 output
|
lda #$ff ; RB 0-7 output
|
||||||
sta LCD_IO+IO::DDRB
|
sta lcd::LCD_IO+IO::DDRB
|
||||||
|
|
||||||
; UT_update_with_mask LCD_IO + IO::DDRA, (LCD_RS | LCD_RW | LCD_E), (LCD_RS | LCD_RW | LCD_E)
|
; UT_update_with_mask IO + IO::DDRA, (RS | LCD_RW | LCD_E), (LCD_RS | LCD_RW | LCD_E)
|
||||||
lda #(LCD_RS | LCD_RW | LCD_E) ; RA 5-7 output
|
lda #(lcd::RS | lcd::RW | lcd::E) ; RA 5-7 output
|
||||||
sta LCD_IO+IO::DDRA
|
sta lcd::LCD_IO+IO::DDRA
|
||||||
|
|
||||||
; init lcd
|
; init lcd
|
||||||
lda #LCD_CMD_FUNCTION_SET
|
lda #lcd::CMD_FUNCTION_SET
|
||||||
jsr _lcd_cmd
|
jsr _cmd
|
||||||
lda #LCD_CMD_DISPLAY_ON
|
lda #lcd::CMD_DISPLAY_ON
|
||||||
jsr _lcd_cmd
|
jsr _cmd
|
||||||
lda #LCD_CMD_CLEAR
|
lda #lcd::CMD_CLEAR
|
||||||
jsr _lcd_cmd
|
jsr _cmd
|
||||||
lda #LCD_CMD_ENTRY_MODE
|
lda #lcd::CMD_ENTRY_MODE
|
||||||
jsr _lcd_cmd
|
jsr _cmd
|
||||||
|
|
||||||
stz LCD_CHARCOUNT
|
stz charcount
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
;********************************************************************************
|
|
||||||
; PRINTING TO LCD
|
|
||||||
;********************************************************************************
|
|
||||||
|
|
||||||
;********************************************************************************
|
|
||||||
; @function Clear the display
|
;;********************************************************************************
|
||||||
; @see lcd_print
|
;; PRINTING TO LCD
|
||||||
;********************************************************************************
|
;;********************************************************************************
|
||||||
.proc lcd_clear
|
|
||||||
stz LCD_CHARCOUNT
|
;;********************************************************************************
|
||||||
lda #LCD_CLEAR
|
;; @function Clear the display
|
||||||
jsr _lcd_cmd
|
;; @see lcd_print
|
||||||
lda #(LCD_CMD_SET_ADDRESS | LCD_LINE1)
|
;; @modifies A
|
||||||
jsr _lcd_cmd
|
;;********************************************************************************
|
||||||
|
.proc clear
|
||||||
|
stz charcount
|
||||||
|
lda #lcd::CLEAR
|
||||||
|
jsr _cmd
|
||||||
|
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE1)
|
||||||
|
jsr _cmd
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
;********************************************************************************
|
;;********************************************************************************
|
||||||
; @function Print a null-terminated string
|
;; @function Print a null-terminated string
|
||||||
; @param ARG0-1 Address of the string to print
|
;; @param ARG0-1 Address of the string to print
|
||||||
;********************************************************************************
|
;; @modifies: A,Y
|
||||||
.proc lcd_print
|
;;********************************************************************************
|
||||||
|
.proc print
|
||||||
ldy #$00
|
ldy #$00
|
||||||
@lcd_print_loop:
|
@lcd_print_loop:
|
||||||
lda (ARG0),y
|
lda (ARG0),y
|
||||||
beq @lcd_print_end
|
beq @lcd_print_end
|
||||||
jsr lcd_char
|
jsr print_char
|
||||||
iny
|
iny
|
||||||
bra @lcd_print_loop
|
bra @lcd_print_loop
|
||||||
@lcd_print_end:
|
@lcd_print_end:
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
;********************************************************************************
|
;;********************************************************************************
|
||||||
; @macro Print a null-terminated string
|
;; @macro Print a single character
|
||||||
; @param message: Address of the message
|
;; @param A: Character to print
|
||||||
;********************************************************************************
|
;;********************************************************************************
|
||||||
.macro Print message
|
.proc print_char
|
||||||
jsr lcd_clear
|
|
||||||
lda #.LOBYTE(message)
|
|
||||||
sta ARG0
|
|
||||||
lda #.HIBYTE(message)
|
|
||||||
sta ARG1
|
|
||||||
jsr lcd_print
|
|
||||||
.endmacro
|
|
||||||
|
|
||||||
;********************************************************************************
|
|
||||||
; @macro Print a single character
|
|
||||||
; @param A: Character to print
|
|
||||||
;********************************************************************************
|
|
||||||
.proc lcd_char
|
|
||||||
pha
|
pha
|
||||||
pha
|
pha
|
||||||
; TODO use UT_update_with_mask?
|
; TODO use UT_update_with_mask?
|
||||||
jsr _lcd_wait_nbusy
|
jsr _wait_nbusy
|
||||||
pla
|
pla
|
||||||
sta LCD_IO + IO::RB
|
sta lcd::LCD_IO + IO::RB
|
||||||
lda #LCD_RS
|
lda #lcd::RS
|
||||||
sta LCD_IO + IO::RA
|
sta lcd::LCD_IO + IO::RA
|
||||||
lda #(LCD_RS | LCD_E)
|
lda #(lcd::RS | lcd::E)
|
||||||
sta LCD_IO + IO::RA
|
sta lcd::LCD_IO + IO::RA
|
||||||
lda #LCD_RS
|
lda #lcd::RS
|
||||||
sta LCD_IO + IO::RA
|
sta lcd::LCD_IO + IO::RA
|
||||||
inc LCD_CHARCOUNT
|
inc charcount
|
||||||
jsr _lcd_set_address
|
jsr _break_line
|
||||||
pla ; put char back in a
|
pla ; put char back in a
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
;********************************************************************************
|
;;********************************************************************************
|
||||||
; Internal LCD Commands
|
;; Internal LCD Commands
|
||||||
;********************************************************************************
|
;;********************************************************************************
|
||||||
; read busy flag
|
; read busy flag
|
||||||
.proc _lcd_wait_nbusy
|
.proc _wait_nbusy
|
||||||
stz LCD_IO + IO::DDRB ; set IO1-LCD_IO + IO::RB to input
|
stz lcd::LCD_IO + IO::DDRB ; set IO1-IO + IO::RB to input
|
||||||
@lcd_wait_nbusy_loop: ; read the busy flag
|
@lcd_wait_nbusy_loop: ; read the busy flag
|
||||||
lda #LCD_RW
|
lda #lcd::RW
|
||||||
sta LCD_IO + IO::RA
|
sta lcd::LCD_IO + IO::RA
|
||||||
lda #(LCD_RW | LCD_E)
|
lda #(lcd::RW | lcd::E)
|
||||||
sta LCD_IO + IO::RA
|
sta lcd::LCD_IO + IO::RA
|
||||||
|
|
||||||
lda LCD_IO + IO::RB
|
lda lcd::LCD_IO + IO::RB
|
||||||
and #%10000000 ; and updates zero flag, if not set retry
|
and #%10000000 ; and updates zero flag, if not set retry
|
||||||
bne @lcd_wait_nbusy_loop
|
bne @lcd_wait_nbusy_loop
|
||||||
|
|
||||||
lda #%00000000 ; TODO dont overwrite 0-4
|
lda #%00000000 ; TODO dont overwrite 0-4
|
||||||
sta LCD_IO + IO::RA
|
sta lcd::LCD_IO + IO::RA
|
||||||
lda #%11111111 ; set IO1-LCD_IO + IO::RB to output
|
lda #%11111111 ; set IO1-IO + IO::RB to output
|
||||||
sta LCD_IO + IO::DDRB
|
sta lcd::LCD_IO + IO::DDRB
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
.proc _lcd_cmd ; send cmd in acc
|
;;********************************************************************************
|
||||||
|
;; @function Send a command to the lcd
|
||||||
|
;; @param A: command
|
||||||
|
;; @modifies A
|
||||||
|
;;********************************************************************************
|
||||||
|
.proc _cmd ; send cmd in acc
|
||||||
pha
|
pha
|
||||||
jsr _lcd_wait_nbusy
|
jsr _wait_nbusy
|
||||||
pla
|
pla
|
||||||
|
|
||||||
; TODO use UT_update_with_mask?
|
; TODO use UT_update_with_mask?
|
||||||
sta LCD_IO + IO::RB
|
sta lcd::LCD_IO + IO::RB
|
||||||
lda #LCD_CLEAR
|
lda #lcd::CLEAR
|
||||||
sta LCD_IO + IO::RA
|
sta lcd::LCD_IO + IO::RA
|
||||||
lda #LCD_E
|
lda #lcd::E
|
||||||
sta LCD_IO + IO::RA
|
sta lcd::LCD_IO + IO::RA
|
||||||
lda #LCD_CLEAR
|
lda #lcd::CLEAR
|
||||||
sta LCD_IO + IO::RA
|
sta lcd::LCD_IO + IO::RA
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
;********************************************************************************
|
;;********************************************************************************
|
||||||
; Set the LCD DD-RAM Address so that text linebreaks after 16 chars
|
;; @function Set the cursor to a position
|
||||||
;********************************************************************************
|
;; @param A: cursor position: `(lcd::LINEX + offset)`, where offset € [$0, $f]
|
||||||
.proc _lcd_set_address
|
;; @details:
|
||||||
|
;; If the position is too large, it will be set to char 5 in line 2
|
||||||
|
;; @returns A: the cursor position
|
||||||
|
;;********************************************************************************
|
||||||
|
.proc set_position
|
||||||
|
cmp #$40
|
||||||
|
bge @invalid
|
||||||
|
sta charcount
|
||||||
|
pha
|
||||||
|
ora #lcd::CMD_SET_ADDRESS
|
||||||
|
jsr _cmd
|
||||||
|
pla
|
||||||
|
@rts:
|
||||||
|
rts
|
||||||
|
@invalid:
|
||||||
|
lda $14
|
||||||
|
sta charcount
|
||||||
|
lda #(lcd::CMD_SET_ADDRESS | (lcd::LINE2 + 4))
|
||||||
|
jsr _cmd
|
||||||
|
lda #(lcd::LINE2 + 4)
|
||||||
|
bra @rts
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @function Set the LCD DD-RAM Address so that text linebreaks after 16 chars
|
||||||
|
;;********************************************************************************
|
||||||
|
.proc _break_line
|
||||||
; check if checks are necessary
|
; check if checks are necessary
|
||||||
lda LCD_CHARCOUNT
|
lda charcount
|
||||||
beq @lcd_line1
|
beq @line1
|
||||||
and #%10001111 ; ($10 | $20 | $30 | $40) = %01110000
|
and #%10001111 ; ($10 | $20 | $30 | $40) = %01110000
|
||||||
bne @lcd_set_address_done
|
bne @rts
|
||||||
; checks necessary
|
; checks necessary
|
||||||
lda LCD_CHARCOUNT
|
lda charcount
|
||||||
beq @lcd_line1
|
beq @line1
|
||||||
cmp #$10
|
cmp #$10
|
||||||
beq @lcd_line2
|
beq @line2
|
||||||
cmp #$20
|
cmp #$20
|
||||||
beq @lcd_line3
|
beq @line3
|
||||||
cmp #$30
|
cmp #$30
|
||||||
beq @lcd_line4
|
beq @line4
|
||||||
cmp #$40 ; set to line1 when full ; set to line1 when full
|
cmp #$40 ; set to line1 when full
|
||||||
beq @lcd_line1
|
bge @line1
|
||||||
@lcd_set_address_done:
|
@rts:
|
||||||
rts
|
rts
|
||||||
@lcd_line1:
|
@line1:
|
||||||
stz LCD_CHARCOUNT
|
stz charcount
|
||||||
lda #(LCD_CMD_SET_ADDRESS | LCD_LINE1)
|
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE1)
|
||||||
jsr _lcd_cmd
|
jsr _cmd
|
||||||
rts
|
rts
|
||||||
@lcd_line2:
|
@line2:
|
||||||
lda #(LCD_CMD_SET_ADDRESS | LCD_LINE2)
|
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE2)
|
||||||
jsr _lcd_cmd
|
jsr _cmd
|
||||||
rts
|
rts
|
||||||
@lcd_line3:
|
@line3:
|
||||||
lda #(LCD_CMD_SET_ADDRESS | LCD_LINE3)
|
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE3)
|
||||||
jsr _lcd_cmd
|
jsr _cmd
|
||||||
rts
|
rts
|
||||||
@lcd_line4:
|
@line4:
|
||||||
lda #(LCD_CMD_SET_ADDRESS | LCD_LINE4)
|
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE4)
|
||||||
jsr _lcd_cmd
|
jsr _cmd
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
.endif
|
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
.segment "ZP"
|
|
||||||
.org 0
|
|
||||||
.byte NULL
|
|
||||||
.org $10
|
|
||||||
.byte ARG0
|
|
||||||
.byte ARG1
|
|
||||||
.byte ARG2
|
|
||||||
.byte ARG3
|
|
||||||
.byte ARG4
|
|
||||||
.byte ARG5
|
|
||||||
.byte ARG6
|
|
||||||
.byte ARG7
|
|
||||||
.byte ARG8
|
|
||||||
.byte ARG9
|
|
||||||
.byte ARG10
|
|
||||||
.byte ARG11
|
|
||||||
.byte ARG12
|
|
||||||
.byte ARG13
|
|
||||||
.byte ARG14
|
|
||||||
.byte ARG15
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.segment "RAM"
|
|
||||||
|
|
||||||
.segment "SPI"
|
|
||||||
.byte SPI_BYTES_WRITTEN
|
|
||||||
.byte SPI_PAGES_WRITTEN
|
|
||||||
.byte
|
|
18
system/spi.h65
Normal file
18
system/spi.h65
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
;********************************************************************************
|
||||||
|
; @module SPI
|
||||||
|
; @type driver
|
||||||
|
; @details
|
||||||
|
; @depends IO-W65C22N
|
||||||
|
;********************************************************************************
|
||||||
|
.ifndef INCLUDE_SPI
|
||||||
|
INCLUDE_SPI = 1
|
||||||
|
|
||||||
|
.include "system/system.h65"
|
||||||
|
|
||||||
|
.scope spi_p
|
||||||
|
SPI_IO = IO2
|
||||||
|
.import CODE_START:absolute
|
||||||
|
Import spi_p, begin, end, read, pages_written, bytes_written
|
||||||
|
|
||||||
|
.endscope
|
||||||
|
.endif ; guard
|
165
system/spi.s65
165
system/spi.s65
@ -1,156 +1,17 @@
|
|||||||
;********************************************************************************
|
.include "spi.h65"
|
||||||
; @module SPI
|
|
||||||
; @type driver
|
|
||||||
; @details
|
|
||||||
; @depends IO-W65C22N
|
|
||||||
;********************************************************************************
|
|
||||||
|
|
||||||
.include "system/system.s65"
|
|
||||||
.include "programs/print_slow.s65"
|
|
||||||
|
|
||||||
.ifndef INCLUDE_SPI
|
|
||||||
INCLUDE_SPI = 1
|
|
||||||
.scope spi_p
|
|
||||||
|
|
||||||
|
Export spi_p, begin, end, read, pages_written, bytes_written
|
||||||
|
|
||||||
.zeropage
|
.zeropage
|
||||||
code_page: .res 2 ; SPI_CODE_START + pages_written * 256
|
code_page: .res 2 ; CODE_START + pages_written * 256
|
||||||
.bss
|
.bss
|
||||||
bytes_written: .res 1
|
bytes_written: .res 1
|
||||||
pages_written: .res 1
|
pages_written: .res 1
|
||||||
|
|
||||||
.include "util/math.s65"
|
SPI_IO := spi_p::SPI_IO
|
||||||
|
CODE_START := spi_p::CODE_START
|
||||||
|
|
||||||
; spi-transferred code will be placed here
|
; spi-transferred code will be placed here
|
||||||
.segment "SPI"
|
|
||||||
SPI_CODE_START:
|
|
||||||
lda '$'
|
|
||||||
jsr lcd_char
|
|
||||||
lda #<TEST_FMT
|
|
||||||
sta ARG0
|
|
||||||
lda #>TEST_FMT
|
|
||||||
sta ARG1
|
|
||||||
lda #<TEST_OUT
|
|
||||||
sta ARG2
|
|
||||||
lda #>TEST_OUT
|
|
||||||
sta ARG3
|
|
||||||
lda #$a9
|
|
||||||
sta ARG4
|
|
||||||
lda #$3c
|
|
||||||
sta ARG5
|
|
||||||
lda #$10
|
|
||||||
sta ARG6
|
|
||||||
jsr strf
|
|
||||||
Print TEST_OUT
|
|
||||||
@spiloop:
|
|
||||||
lda IO1 + IO::RA
|
|
||||||
lda IO2 + IO::RA
|
|
||||||
nop
|
|
||||||
bra @spiloop
|
|
||||||
jmp home
|
|
||||||
|
|
||||||
; TODO allocate zp memory
|
|
||||||
fmt_idx = $30
|
|
||||||
out_idx = $31
|
|
||||||
;********************************************************************************
|
|
||||||
; @function Format a string
|
|
||||||
; @details
|
|
||||||
; If there is no value to be read, the Pz will be set
|
|
||||||
; Formats:
|
|
||||||
; - u: unsigned decimal integer (1 byte)
|
|
||||||
; - U: unsigned decimal integer (2 bytes)
|
|
||||||
; @param ARG0-1: Format string address
|
|
||||||
; @param ARG2-3: Output string address
|
|
||||||
; @param ARG4+: Additional parameters
|
|
||||||
; @returns
|
|
||||||
; @modifies: A, Y
|
|
||||||
;********************************************************************************
|
|
||||||
.proc strf
|
|
||||||
stz out_idx
|
|
||||||
stz fmt_idx
|
|
||||||
ldy #0 ; position in string
|
|
||||||
ldx #0 ; index of format args
|
|
||||||
@loop:
|
|
||||||
ldy fmt_idx
|
|
||||||
lda (ARG0),y
|
|
||||||
beq @null
|
|
||||||
cmp #'%'
|
|
||||||
beq @percent
|
|
||||||
@normal_char: ; store A in output string
|
|
||||||
ldy out_idx
|
|
||||||
sta (ARG2),y
|
|
||||||
inc fmt_idx
|
|
||||||
inc out_idx
|
|
||||||
beq @out_overflow
|
|
||||||
bra @loop
|
|
||||||
@percent: ; check for format in next position
|
|
||||||
iny
|
|
||||||
sty fmt_idx
|
|
||||||
lda (ARG0),y
|
|
||||||
beq @null
|
|
||||||
; formats
|
|
||||||
cmp #'x'
|
|
||||||
beq @format_hex1
|
|
||||||
bra @normal_char
|
|
||||||
@format_hex1: ; 1 byte hex -> 2 chars
|
|
||||||
lda ARG4,x
|
|
||||||
phx
|
|
||||||
jsr int8_to_hex_str
|
|
||||||
ldy out_idx
|
|
||||||
sta (ARG2),y ; most sig digit
|
|
||||||
iny
|
|
||||||
beq @out_overflow
|
|
||||||
txa
|
|
||||||
sta (ARG2),y ; least sig digit
|
|
||||||
iny
|
|
||||||
beq @out_overflow
|
|
||||||
sty out_idx
|
|
||||||
plx
|
|
||||||
inx ; 1 byte of args handeled
|
|
||||||
; bra @format_return
|
|
||||||
@format_return: ; increment fmt_idx to swallow the formating char
|
|
||||||
inc fmt_idx
|
|
||||||
bra @loop
|
|
||||||
@out_overflow: ; store 0 in last position
|
|
||||||
ldy #$ff
|
|
||||||
sty out_idx
|
|
||||||
@store_null:
|
|
||||||
lda #0
|
|
||||||
@null: ; store and return
|
|
||||||
ldy out_idx
|
|
||||||
sta (ARG2),y
|
|
||||||
@rts:
|
|
||||||
rts
|
|
||||||
.endproc
|
|
||||||
|
|
||||||
|
|
||||||
;********************************************************************************
|
|
||||||
; @function Convert a 1 byte number into two hex characters
|
|
||||||
; @param A: Number to convert
|
|
||||||
; @returns A: Most significant digit
|
|
||||||
; @returns X: Least significant digit
|
|
||||||
; @modifies X,Y,A
|
|
||||||
;********************************************************************************
|
|
||||||
.proc int8_to_hex_str
|
|
||||||
pha
|
|
||||||
and #%00001111
|
|
||||||
tay
|
|
||||||
ldx HEX_CHARS,y
|
|
||||||
pla
|
|
||||||
div A,16
|
|
||||||
and #%00001111
|
|
||||||
tay
|
|
||||||
lda HEX_CHARS,y
|
|
||||||
rts
|
|
||||||
.endproc
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
HEX_CHARS: .byte "0123456789ABCDEF"
|
|
||||||
|
|
||||||
TEST_FMT: .asciiz "%x -> %x -> %x:)"
|
|
||||||
TEST_OUT: .asciiz "TESTOUT"
|
|
||||||
|
|
||||||
; SPI_P = as peripheral
|
; SPI_P = as peripheral
|
||||||
.code
|
.code
|
||||||
.struct SPI_P_Pins
|
.struct SPI_P_Pins
|
||||||
@ -178,9 +39,9 @@ TEST_OUT: .asciiz "TESTOUT"
|
|||||||
stz pages_written
|
stz pages_written
|
||||||
stz bytes_written
|
stz bytes_written
|
||||||
; store address in zp
|
; store address in zp
|
||||||
lda #<SPI_CODE_START
|
lda #<CODE_START
|
||||||
sta code_page
|
sta code_page
|
||||||
lda #>SPI_CODE_START
|
lda #>CODE_START
|
||||||
sta code_page + 1
|
sta code_page + 1
|
||||||
; todo USE MASKS
|
; todo USE MASKS
|
||||||
; set Shift register to shift in under external clock on CB1
|
; set Shift register to shift in under external clock on CB1
|
||||||
@ -196,6 +57,7 @@ TEST_OUT: .asciiz "TESTOUT"
|
|||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
;********************************************************************************
|
;********************************************************************************
|
||||||
; @function Stop listening for SPI transfers
|
; @function Stop listening for SPI transfers
|
||||||
; @details
|
; @details
|
||||||
@ -209,7 +71,6 @@ TEST_OUT: .asciiz "TESTOUT"
|
|||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;********************************************************************************
|
;********************************************************************************
|
||||||
; @function Read a byte from SPI
|
; @function Read a byte from SPI
|
||||||
; @details
|
; @details
|
||||||
@ -218,7 +79,7 @@ TEST_OUT: .asciiz "TESTOUT"
|
|||||||
.proc read
|
.proc read
|
||||||
ldx bytes_written
|
ldx bytes_written
|
||||||
lda SPI_IO + IO::SR
|
lda SPI_IO + IO::SR
|
||||||
sta SPI_CODE_START,x
|
sta CODE_START,x
|
||||||
inc bytes_written
|
inc bytes_written
|
||||||
beq @new_page
|
beq @new_page
|
||||||
rts
|
rts
|
||||||
@ -249,9 +110,3 @@ TEST_OUT: .asciiz "TESTOUT"
|
|||||||
;********************************************************************************
|
;********************************************************************************
|
||||||
.proc send_data
|
.proc send_data
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
.endscope
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.endif
|
|
||||||
|
55
system/system.h65
Normal file
55
system/system.h65
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
;********************************************************************************
|
||||||
|
; @module system
|
||||||
|
; @type header
|
||||||
|
; @details
|
||||||
|
; Variable definitions for the current hardware setup
|
||||||
|
;********************************************************************************
|
||||||
|
|
||||||
|
.ifndef INCLUDE_SYSTEM
|
||||||
|
INCLUDE_SYSTEM = 1
|
||||||
|
; reserved RAM addresses
|
||||||
|
; 00-0f - free
|
||||||
|
; 10-1f - arguments / return values
|
||||||
|
; 20-ff - free
|
||||||
|
; 0100 - 01FF Stack
|
||||||
|
; 0200,0201 keybuffer write/read pointer
|
||||||
|
; 0202-02ff keybuffer
|
||||||
|
; 0300 lcd character counter
|
||||||
|
; 0400, 0401, 0402 dht status, dht bit, dht_bit_rot
|
||||||
|
; 0403 value offset
|
||||||
|
; 0405-04a0 rh high/low, temp high/low, checksum
|
||||||
|
|
||||||
|
.include "io_W65C22.h65"
|
||||||
|
.include "utility.h65"
|
||||||
|
|
||||||
|
; ARGUMENTS
|
||||||
|
; a,x,y can also be used
|
||||||
|
ARG0 = $10
|
||||||
|
ARG1 = $11
|
||||||
|
ARG2 = $12
|
||||||
|
ARG3 = $13
|
||||||
|
ARG4 = $14
|
||||||
|
ARG5 = $15
|
||||||
|
ARG6 = $16
|
||||||
|
ARG7 = $17
|
||||||
|
ARG9 = $19
|
||||||
|
ARG10 = $1a
|
||||||
|
ARG11 = $1b
|
||||||
|
ARG12 = $1c
|
||||||
|
ARG13 = $1d
|
||||||
|
ARG14 = $1e
|
||||||
|
ARG15 = $1f
|
||||||
|
|
||||||
|
|
||||||
|
; RETURN VALUE
|
||||||
|
; in a
|
||||||
|
|
||||||
|
.segment "VIA1"
|
||||||
|
; IO1: .res 16
|
||||||
|
IO1 = $6000
|
||||||
|
|
||||||
|
.segment "VIA2"
|
||||||
|
; IO2: .res 16
|
||||||
|
IO2 = $7000
|
||||||
|
|
||||||
|
.endif ; include guard
|
@ -1,82 +1,3 @@
|
|||||||
;********************************************************************************
|
.zeropage
|
||||||
; @module system
|
.org $10
|
||||||
; @type header
|
.res 16
|
||||||
; @details
|
|
||||||
; Variable definitions for the current hardware setup
|
|
||||||
;********************************************************************************
|
|
||||||
|
|
||||||
.ifndef INCLUDE_SYSTEM
|
|
||||||
INCLUDE_SYSTEM = 1
|
|
||||||
; reserved RAM addresses
|
|
||||||
; 00-0f - free
|
|
||||||
; 10-1f - arguments / return values
|
|
||||||
; 20-ff - free
|
|
||||||
; 0100 - 01FF Stack
|
|
||||||
; 0200,0201 keybuffer write/read pointer
|
|
||||||
; 0202-02ff keybuffer
|
|
||||||
; 0300 lcd character counter
|
|
||||||
; 0400, 0401, 0402 dht status, dht bit, dht_bit_rot
|
|
||||||
; 0403 value offset
|
|
||||||
; 0405-04a0 rh high/low, temp high/low, checksum
|
|
||||||
|
|
||||||
.include "io_W65C22.h65"
|
|
||||||
.include "utility.h65"
|
|
||||||
|
|
||||||
; ARGUMENTS
|
|
||||||
; a,x,y can also be used
|
|
||||||
.segment "ZEROPAGE"
|
|
||||||
ARG0: .res 1
|
|
||||||
ARG1: .res 1
|
|
||||||
ARG2: .res 1
|
|
||||||
ARG3: .res 1
|
|
||||||
ARG4: .res 1
|
|
||||||
ARG5: .res 1
|
|
||||||
ARG6: .res 1
|
|
||||||
ARG7: .res 1
|
|
||||||
ARG9: .res 1
|
|
||||||
ARG10: .res 1
|
|
||||||
ARG11: .res 1
|
|
||||||
ARG12: .res 1
|
|
||||||
ARG13: .res 1
|
|
||||||
ARG14: .res 1
|
|
||||||
ARG15: .res 1
|
|
||||||
|
|
||||||
|
|
||||||
; RETURN VALUE
|
|
||||||
; in a
|
|
||||||
|
|
||||||
.segment "VIA1"
|
|
||||||
; IO1: .res 16
|
|
||||||
IO1 = $6000
|
|
||||||
|
|
||||||
.segment "VIA2"
|
|
||||||
; IO2: .res 16
|
|
||||||
IO2 = $7000
|
|
||||||
|
|
||||||
; struct method
|
|
||||||
; .org $6000
|
|
||||||
; VIA1: .tag VIA_Pins
|
|
||||||
; .org $7000
|
|
||||||
; VIA2: .tag VIA_Pins
|
|
||||||
|
|
||||||
; ; IO-1
|
|
||||||
; PB1 = $6000
|
|
||||||
; PA1 = $6001
|
|
||||||
; DDRB1 = $6002
|
|
||||||
; DDRA1 = $6003
|
|
||||||
; T1L1 = $6004
|
|
||||||
; T1H1 = $6005
|
|
||||||
; ; IO-2
|
|
||||||
; PB2 = $7000
|
|
||||||
; PA2 = $7001
|
|
||||||
; DDRB2 = $7002
|
|
||||||
; DDRA2 = $7003
|
|
||||||
; T1L2 = $7004
|
|
||||||
; T1H2 = $7005
|
|
||||||
; ACR2 = $700b
|
|
||||||
; PCR2 = $700c
|
|
||||||
; IFR2 = $700d
|
|
||||||
; IER2 = $700e
|
|
||||||
|
|
||||||
|
|
||||||
.endif ; include guard
|
|
||||||
|
98
test.s65
98
test.s65
@ -1,55 +1,55 @@
|
|||||||
.include "system/system.h65"
|
;.include "system/system.h65"
|
||||||
.segment "CODE"
|
;.segment "CODE"
|
||||||
|
|
||||||
;********************************************************************************
|
;;********************************************************************************
|
||||||
; Interrupts
|
;; Interrupts
|
||||||
;********************************************************************************
|
;;********************************************************************************
|
||||||
nmi:
|
;nmi:
|
||||||
rti
|
; rti
|
||||||
irq:
|
;irq:
|
||||||
.repeat 20
|
; .repeat 20
|
||||||
.endrepeat
|
; .endrepeat
|
||||||
rti
|
; rti
|
||||||
|
|
||||||
;********************************************************************************
|
;;********************************************************************************
|
||||||
; Reset sequence
|
;; Reset sequence
|
||||||
;********************************************************************************
|
;;********************************************************************************
|
||||||
reset:
|
;reset:
|
||||||
sei
|
; sei
|
||||||
; setup io2 bank a 1-3
|
; ; setup io2 bank a 1-3
|
||||||
lda #%11111111
|
; lda #%11111111
|
||||||
sta IO1 + IO_DDRA
|
; sta IO1 + IO_DDRA
|
||||||
sta IO1 + IO_DDRB
|
; sta IO1 + IO_DDRB
|
||||||
|
|
||||||
@loop:
|
;@loop:
|
||||||
lda #%00000000
|
; lda #%00000000
|
||||||
sta IO1 + IO_RA
|
; sta IO1 + IO_RA
|
||||||
.repeat 3
|
; .repeat 3
|
||||||
nop
|
; nop
|
||||||
.endrepeat
|
; .endrepeat
|
||||||
lda #%11111111
|
; lda #%11111111
|
||||||
sta IO1 + IO_RA
|
; sta IO1 + IO_RA
|
||||||
.repeat 15
|
; .repeat 15
|
||||||
nop
|
; nop
|
||||||
.endrepeat
|
; .endrepeat
|
||||||
|
|
||||||
lda #%00000000
|
; lda #%00000000
|
||||||
sta IO1 + IO_RB
|
; sta IO1 + IO_RB
|
||||||
.repeat 5
|
; .repeat 5
|
||||||
nop
|
; nop
|
||||||
.endrepeat
|
; .endrepeat
|
||||||
lda #%11111111
|
; lda #%11111111
|
||||||
sta IO1 + IO_RB
|
; sta IO1 + IO_RB
|
||||||
.repeat 10
|
; .repeat 10
|
||||||
nop
|
; nop
|
||||||
.endrepeat
|
; .endrepeat
|
||||||
bra @loop
|
; bra @loop
|
||||||
|
|
||||||
;********************************************************************************
|
;;********************************************************************************
|
||||||
; reset vector
|
;; reset vector
|
||||||
;********************************************************************************
|
;;********************************************************************************
|
||||||
.segment "RESET_VECTOR"
|
;.segment "RESET_VECTOR"
|
||||||
.word nmi
|
; .word nmi
|
||||||
.word reset
|
; .word reset
|
||||||
.word irq
|
; .word irq
|
||||||
|
|
||||||
|
107
util/math.h65
Normal file
107
util/math.h65
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
;********************************************************************************
|
||||||
|
; @module math
|
||||||
|
; @type utility
|
||||||
|
; @details
|
||||||
|
; Math library
|
||||||
|
;********************************************************************************
|
||||||
|
.ifndef INCLUDE_MATH
|
||||||
|
INCLUDE_MATH = 1
|
||||||
|
|
||||||
|
.scope math
|
||||||
|
|
||||||
|
;********************************************************************************
|
||||||
|
; @macro Divide a num (or A) by a factor
|
||||||
|
; @param num: Memory or A
|
||||||
|
; @param divider: must be power of 2
|
||||||
|
;********************************************************************************
|
||||||
|
.macro div num,divider
|
||||||
|
.if divider = 2
|
||||||
|
lsr num
|
||||||
|
.elseif divider = 4
|
||||||
|
lsr num
|
||||||
|
lsr num
|
||||||
|
.elseif divider = 8
|
||||||
|
lsr num
|
||||||
|
lsr num
|
||||||
|
lsr num
|
||||||
|
.elseif divider = 16
|
||||||
|
.repeat 4
|
||||||
|
lsr num
|
||||||
|
.endrepeat
|
||||||
|
.elseif divider = 32
|
||||||
|
.repeat 5
|
||||||
|
lsr num
|
||||||
|
.endrepeat
|
||||||
|
.elseif divider = 64
|
||||||
|
.repeat 6
|
||||||
|
lsr num
|
||||||
|
.endrepeat
|
||||||
|
.elseif divider = 128
|
||||||
|
.repeat 7
|
||||||
|
lsr num
|
||||||
|
.endrepeat
|
||||||
|
.else
|
||||||
|
.error "div macro: divider % 2 != 0"
|
||||||
|
.endif
|
||||||
|
.endmacro
|
||||||
|
|
||||||
|
; .macro Amult1 factor
|
||||||
|
; phx
|
||||||
|
; ldx factor
|
||||||
|
; AmultX
|
||||||
|
; plx
|
||||||
|
; .endmacro
|
||||||
|
|
||||||
|
; https://www.llx.com/Neil/a2/mult.html
|
||||||
|
; .macro mult num1,num2,result
|
||||||
|
; lda #0
|
||||||
|
; ldx #8
|
||||||
|
; L1:
|
||||||
|
; lsr num2
|
||||||
|
; bcc L2
|
||||||
|
; clc
|
||||||
|
; adc num1
|
||||||
|
; L2:
|
||||||
|
; ror
|
||||||
|
; ror result
|
||||||
|
; dex
|
||||||
|
; bne L1
|
||||||
|
; sta result+1
|
||||||
|
; .endmacro
|
||||||
|
|
||||||
|
; 00110101
|
||||||
|
; 10010011
|
||||||
|
; -------^
|
||||||
|
; =00110101
|
||||||
|
; 00110101
|
||||||
|
; 01001001
|
||||||
|
; -------^
|
||||||
|
; =00110101
|
||||||
|
; 00110101
|
||||||
|
; 00100100
|
||||||
|
; -------^
|
||||||
|
; =00000000
|
||||||
|
; 00110101
|
||||||
|
; 00010010
|
||||||
|
; -------^
|
||||||
|
; =00000000
|
||||||
|
; 00110101
|
||||||
|
; 00001001
|
||||||
|
; -------^
|
||||||
|
; 00110101
|
||||||
|
; 00110101
|
||||||
|
; 00000100
|
||||||
|
; -------^
|
||||||
|
; =00000000
|
||||||
|
; 00110101
|
||||||
|
; 00000010
|
||||||
|
; -------^
|
||||||
|
; =00000000
|
||||||
|
; 00110101
|
||||||
|
; 00000001
|
||||||
|
; 00110101
|
||||||
|
|
||||||
|
|
||||||
|
.endscope
|
||||||
|
.endif ; guard
|
||||||
|
|
107
util/math.s65
107
util/math.s65
@ -1,106 +1 @@
|
|||||||
;********************************************************************************
|
.code
|
||||||
; @module math
|
|
||||||
; @type utility
|
|
||||||
; @details
|
|
||||||
; Math library
|
|
||||||
;********************************************************************************
|
|
||||||
.ifndef INCLUDE_MATH
|
|
||||||
INCLUDE_MATH = 1
|
|
||||||
|
|
||||||
.scope math
|
|
||||||
|
|
||||||
;********************************************************************************
|
|
||||||
; @macro Divide a num (or A) by a factor
|
|
||||||
; @param num: Memory or A
|
|
||||||
; @param divider: must be power of 2
|
|
||||||
;********************************************************************************
|
|
||||||
.macro div num,divider
|
|
||||||
.if divider = 2
|
|
||||||
lsr num
|
|
||||||
.elseif divider = 4
|
|
||||||
lsr num
|
|
||||||
lsr num
|
|
||||||
.elseif divider = 8
|
|
||||||
lsr num
|
|
||||||
lsr num
|
|
||||||
lsr num
|
|
||||||
.elseif divider = 16
|
|
||||||
.repeat 4
|
|
||||||
lsr num
|
|
||||||
.endrepeat
|
|
||||||
.elseif divider = 32
|
|
||||||
.repeat 5
|
|
||||||
lsr num
|
|
||||||
.endrepeat
|
|
||||||
.elseif divider = 64
|
|
||||||
.repeat 6
|
|
||||||
lsr num
|
|
||||||
.endrepeat
|
|
||||||
.elseif divider = 128
|
|
||||||
.repeat 7
|
|
||||||
lsr num
|
|
||||||
.endrepeat
|
|
||||||
.else
|
|
||||||
.error "div macro: divider % 2 != 0"
|
|
||||||
.endif
|
|
||||||
.endmacro
|
|
||||||
|
|
||||||
; .macro Amult1 factor
|
|
||||||
; phx
|
|
||||||
; ldx factor
|
|
||||||
; AmultX
|
|
||||||
; plx
|
|
||||||
; .endmacro
|
|
||||||
|
|
||||||
; https://www.llx.com/Neil/a2/mult.html
|
|
||||||
; .macro mult num1,num2,result
|
|
||||||
; lda #0
|
|
||||||
; ldx #8
|
|
||||||
; L1:
|
|
||||||
; lsr num2
|
|
||||||
; bcc L2
|
|
||||||
; clc
|
|
||||||
; adc num1
|
|
||||||
; L2:
|
|
||||||
; ror
|
|
||||||
; ror result
|
|
||||||
; dex
|
|
||||||
; bne L1
|
|
||||||
; sta result+1
|
|
||||||
; .endmacro
|
|
||||||
|
|
||||||
; 00110101
|
|
||||||
; 10010011
|
|
||||||
; -------^
|
|
||||||
; =00110101
|
|
||||||
; 00110101
|
|
||||||
; 01001001
|
|
||||||
; -------^
|
|
||||||
; =00110101
|
|
||||||
; 00110101
|
|
||||||
; 00100100
|
|
||||||
; -------^
|
|
||||||
; =00000000
|
|
||||||
; 00110101
|
|
||||||
; 00010010
|
|
||||||
; -------^
|
|
||||||
; =00000000
|
|
||||||
; 00110101
|
|
||||||
; 00001001
|
|
||||||
; -------^
|
|
||||||
; 00110101
|
|
||||||
; 00110101
|
|
||||||
; 00000100
|
|
||||||
; -------^
|
|
||||||
; =00000000
|
|
||||||
; 00110101
|
|
||||||
; 00000010
|
|
||||||
; -------^
|
|
||||||
; =00000000
|
|
||||||
; 00110101
|
|
||||||
; 00000001
|
|
||||||
; 00110101
|
|
||||||
|
|
||||||
|
|
||||||
.endscope
|
|
||||||
.endif ; guard
|
|
||||||
|
66
util/string.h65
Normal file
66
util/string.h65
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
;********************************************************************************
|
||||||
|
; @module string
|
||||||
|
; @type utility
|
||||||
|
; @details
|
||||||
|
; String utility
|
||||||
|
;********************************************************************************
|
||||||
|
.ifndef INCLUDE_STRING
|
||||||
|
INCLUDE_STRING = 1
|
||||||
|
|
||||||
|
.include "system/system.h65"
|
||||||
|
|
||||||
|
|
||||||
|
.scope str
|
||||||
|
Import str, strf, int8_to_hex_str
|
||||||
|
|
||||||
|
|
||||||
|
.macro _StrfStoreArg arg
|
||||||
|
.if (.not .blank(arg))
|
||||||
|
.if .match(arg, x)
|
||||||
|
stx ARG4 + @N_ARGS
|
||||||
|
.elseif .match(arg, y)
|
||||||
|
sty ARG4 + @N_ARGS
|
||||||
|
.else
|
||||||
|
lda arg
|
||||||
|
sta ARG4 + @N_ARGS
|
||||||
|
.endif
|
||||||
|
@N_ARGS .set (@N_ARGS + 1)
|
||||||
|
.endif
|
||||||
|
.endmacro
|
||||||
|
|
||||||
|
;********************************************************************************
|
||||||
|
; @function Macro for passing arguments to strf
|
||||||
|
; @param fmt: Format string address
|
||||||
|
; @param out: Output string address
|
||||||
|
; @param x0-x9: Additional parameters
|
||||||
|
; @warning Addresses as additional paramteres must be passed like this `#<addr,#>addr`
|
||||||
|
; @modifies: A, X, Y
|
||||||
|
; @see strf
|
||||||
|
;********************************************************************************
|
||||||
|
.macro Strf fmt,out,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9
|
||||||
|
@N_ARGS .set 0 ; @ so that it doesnt break cheap labels
|
||||||
|
lda #<fmt
|
||||||
|
sta ARG0
|
||||||
|
lda #>fmt
|
||||||
|
sta ARG1
|
||||||
|
lda #<out
|
||||||
|
sta ARG2
|
||||||
|
lda #>out
|
||||||
|
sta ARG3
|
||||||
|
_StrfStoreArg x0
|
||||||
|
_StrfStoreArg x1
|
||||||
|
_StrfStoreArg x2
|
||||||
|
_StrfStoreArg x3
|
||||||
|
_StrfStoreArg x4
|
||||||
|
_StrfStoreArg x5
|
||||||
|
_StrfStoreArg x6
|
||||||
|
_StrfStoreArg x7
|
||||||
|
jsr str::strf
|
||||||
|
.out .sprintf("info: Strf: called with %d arguments", @N_ARGS)
|
||||||
|
.endmacro
|
||||||
|
|
||||||
|
; TODO allocate zp memory
|
||||||
|
fmt_idx = $30
|
||||||
|
out_idx = $31
|
||||||
|
.endscope
|
||||||
|
.endif ; guard
|
@ -1,63 +1,8 @@
|
|||||||
;********************************************************************************
|
.include "string.h65"
|
||||||
; @module string
|
.include "math.h65"
|
||||||
; @type utility
|
Export str, strf, int8_to_hex_str
|
||||||
; @details
|
|
||||||
; String utility
|
|
||||||
;********************************************************************************
|
|
||||||
.ifndef INCLUDE_STRING
|
|
||||||
INCLUDE_STRING = 1
|
|
||||||
|
|
||||||
.scope str
|
|
||||||
|
|
||||||
.code
|
.code
|
||||||
.macro _StrfStoreArg arg
|
|
||||||
.if (.not .blank(arg))
|
|
||||||
.if .match(arg, x)
|
|
||||||
stx ARG4 + @N_ARGS
|
|
||||||
.elseif .match(arg, y)
|
|
||||||
sty ARG4 + @N_ARGS
|
|
||||||
.else
|
|
||||||
lda arg
|
|
||||||
sta ARG4 + @N_ARGS
|
|
||||||
.endif
|
|
||||||
@N_ARGS .set (@N_ARGS + 1)
|
|
||||||
.endif
|
|
||||||
.endmacro
|
|
||||||
|
|
||||||
;********************************************************************************
|
|
||||||
; @function Macro for passing arguments to strf
|
|
||||||
; @param fmt: Format string address
|
|
||||||
; @param out: Output string address
|
|
||||||
; @param x0-x9: Additional parameters
|
|
||||||
; @warning Addresses as additional paramteres must be passed like this `#<addr,#>addr`
|
|
||||||
; @modifies: A, X, Y
|
|
||||||
; @see strf
|
|
||||||
;********************************************************************************
|
|
||||||
.macro Strf fmt,out,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9
|
|
||||||
@N_ARGS .set 0 ; @ so that it doesnt break cheap labels
|
|
||||||
lda #<fmt
|
|
||||||
sta ARG0
|
|
||||||
lda #>fmt
|
|
||||||
sta ARG1
|
|
||||||
lda #<out
|
|
||||||
sta ARG2
|
|
||||||
lda #>out
|
|
||||||
sta ARG3
|
|
||||||
_StrfStoreArg x0
|
|
||||||
_StrfStoreArg x1
|
|
||||||
_StrfStoreArg x2
|
|
||||||
_StrfStoreArg x3
|
|
||||||
_StrfStoreArg x4
|
|
||||||
_StrfStoreArg x5
|
|
||||||
_StrfStoreArg x6
|
|
||||||
_StrfStoreArg x7
|
|
||||||
jsr strf
|
|
||||||
.out .sprintf("info: Strf: called with %d arguments", @N_ARGS)
|
|
||||||
.endmacro
|
|
||||||
|
|
||||||
; TODO allocate zp memory
|
|
||||||
fmt_idx = $30
|
|
||||||
out_idx = $31
|
|
||||||
;********************************************************************************
|
;********************************************************************************
|
||||||
; @function Format a string
|
; @function Format a string
|
||||||
; @details
|
; @details
|
||||||
@ -73,6 +18,8 @@ out_idx = $31
|
|||||||
; @returns
|
; @returns
|
||||||
; @modifies: A, X, Y
|
; @modifies: A, X, Y
|
||||||
;********************************************************************************
|
;********************************************************************************
|
||||||
|
out_idx := str::out_idx
|
||||||
|
fmt_idx := str::fmt_idx
|
||||||
.proc strf
|
.proc strf
|
||||||
stz out_idx
|
stz out_idx
|
||||||
stz fmt_idx
|
stz fmt_idx
|
||||||
@ -156,8 +103,3 @@ out_idx = $31
|
|||||||
.rodata
|
.rodata
|
||||||
HEX_CHARS_UPPER: .byte "0123456789ABCDEF"
|
HEX_CHARS_UPPER: .byte "0123456789ABCDEF"
|
||||||
HEX_CHARS_LOWER: .byte "0123456789abcdef"
|
HEX_CHARS_LOWER: .byte "0123456789abcdef"
|
||||||
|
|
||||||
.export strf
|
|
||||||
|
|
||||||
.endscope
|
|
||||||
.endif ; guard
|
|
||||||
|
56
utility.h65
56
utility.h65
@ -2,6 +2,7 @@
|
|||||||
INCLUDE_UTILITY = 1
|
INCLUDE_UTILITY = 1
|
||||||
|
|
||||||
.macpack longbranch ; jeq, jge...
|
.macpack longbranch ; jeq, jge...
|
||||||
|
.macpack generic ; bge, add, sub
|
||||||
|
|
||||||
;********************************************************************************
|
;********************************************************************************
|
||||||
; @macro Update a byte in memory using a mask
|
; @macro Update a byte in memory using a mask
|
||||||
@ -31,4 +32,59 @@ INCLUDE_UTILITY = 1
|
|||||||
; _n_genlabel .set _n_genlabel + 1
|
; _n_genlabel .set _n_genlabel + 1
|
||||||
;.endmacro
|
;.endmacro
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @macro Export labels with a prefix
|
||||||
|
;; @details
|
||||||
|
;; Equivalent to:
|
||||||
|
;; .export prefix_l1:=l1
|
||||||
|
;; .export prefix_l2:=l2
|
||||||
|
;; ...
|
||||||
|
;;********************************************************************************
|
||||||
|
.macro Export prefix,l1,l2,l3,l4,l5,l6,l7,l8
|
||||||
|
.if .blank(l1)
|
||||||
|
.exitmacro
|
||||||
|
.endif
|
||||||
|
; .out .sprintf("Exporting %s as %s_%s", .string(l1), .string(prefix), .string(l1))
|
||||||
|
.export .ident(.sprintf("%s_%s", .string(prefix), .string(l1))):=l1
|
||||||
|
Export prefix,l2,l3,l4,l5,l6,l7,l8
|
||||||
|
.endmacro
|
||||||
|
.macro ExportZp prefix,l1,l2,l3,l4,l5,l6,l7,l8
|
||||||
|
.if .blank(l1)
|
||||||
|
.exitmacro
|
||||||
|
.endif
|
||||||
|
; .out .sprintf("Exporting (zp) %s as %s_%s", .string(l1), .string(prefix), .string(l1))
|
||||||
|
.exportzp .ident(.sprintf("%s_%s", .string(prefix), .string(l1))):=l1
|
||||||
|
ExportZp prefix,l2,l3,l4,l5,l6,l7,l8
|
||||||
|
.endmacro
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @macro Import labels and remove prefix
|
||||||
|
;; @details
|
||||||
|
;; Equivalent to:
|
||||||
|
;; .import prefix_l1
|
||||||
|
;; .import prefix_l2
|
||||||
|
;; ...
|
||||||
|
;; l1 = prefix_l1
|
||||||
|
;; l2 = prefix_l2
|
||||||
|
;; ...
|
||||||
|
;; Use in a scope to have the lX available as scope::lX
|
||||||
|
;;********************************************************************************
|
||||||
|
.macro Import prefix,l1,l2,l3,l4,l5,l6,l7,l8
|
||||||
|
.if .blank(l1)
|
||||||
|
.exitmacro
|
||||||
|
.endif
|
||||||
|
; .out .sprintf("Importing %s_%s as %s", .string(prefix), .string(l1), .string(l1))
|
||||||
|
.import .ident(.sprintf("%s_%s", .string(prefix), .string(l1))):absolute
|
||||||
|
.ident(.sprintf("%s", .string(l1))) = .ident(.sprintf("%s_%s", .string(prefix), .string(l1)))
|
||||||
|
Import prefix,l2,l3,l4,l5,l6,l7,l8
|
||||||
|
.endmacro
|
||||||
|
.macro ImportZp prefix,l1,l2,l3,l4,l5,l6,l7,l8
|
||||||
|
.if .blank(l1)
|
||||||
|
.exitmacro
|
||||||
|
.endif
|
||||||
|
; .out .sprintf("Importing (zp) %s_%s as %s", .string(prefix), .string(l1), .string(l1))
|
||||||
|
.importzp .ident(.sprintf("%s_%s", .string(prefix), .string(l1))):zeropage
|
||||||
|
.ident(.sprintf("%s", .string(l1))) = .ident(.sprintf("%s_%s", .string(prefix), .string(l1)))
|
||||||
|
ImportZp prefix,l2,l3,l4,l5,l6,l7,l8
|
||||||
|
.endmacro
|
||||||
.endif
|
.endif
|
||||||
|
Loading…
Reference in New Issue
Block a user