refactor with source+header
This commit is contained in:
parent
321759f70d
commit
9a1324a29a
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
**.bin
|
||||
**.o
|
||||
.build
|
||||
.dependencies
|
||||
**.d
|
||||
*build*
|
||||
labels
|
||||
|
51
Makefile
51
Makefile
@ -1,41 +1,54 @@
|
||||
ROM = ../rom.bin
|
||||
|
||||
BUILD_DIR = .build
|
||||
OBJ_DIR = build
|
||||
|
||||
SRC_DIRS = programs system
|
||||
SRC_DIRS = . programs system util
|
||||
|
||||
# VASM = ~/6502/vasm6502
|
||||
ASM = ca65
|
||||
ASMFLAGS = -g --cpu 65C02 $(foreach srcdir, $(SRC_DIRS), -I $(srcdir))
|
||||
ASMDEPFLAGS = --create-dep .dependencies
|
||||
|
||||
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))
|
||||
|
||||
-include .dependencies
|
||||
-include $(DEP)
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir $@
|
||||
|
||||
.PHONY: default test clean
|
||||
.PHONY: default test clean print
|
||||
.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
|
||||
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 $@
|
||||
|
||||
../test.bin: $(BUILD_DIR)/test.o
|
||||
# $(VASM) -dotdir -opt-branch -wdc02 -chklabels test.asm6502
|
||||
$(LD) $(LDFLAGS) $(BUILD_DIR)/test.o -o ../test.bin
|
||||
|
||||
$(BUILD_DIR)/%.o: %.s65 | $(BUILD_DIR)
|
||||
$(ASM) $(ASMFLAGS) $(ASMDEPFLAGS) $< -o $@
|
||||
|
||||
$(OBJ_DIR)/%.o: %.s65 | $(OBJ_DIRS)
|
||||
@printf $(FMT_ASM) "$@" "$<"
|
||||
$(ASM) $(ASMFLAGS) --create-dep $(patsubst %.o,%.d,$@) $< -o $@
|
||||
|
||||
clean:
|
||||
rm -r $(BUILD_DIR)
|
||||
rm -r $(OBJ_DIR)
|
||||
rm $(ROM)
|
||||
|
@ -1,10 +1,11 @@
|
||||
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 = $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;
|
||||
VIA1: start = $6000, size = $600f, type = rw, file = "", fill = yes;
|
||||
VIA2: start = $7000, size = $700f, type = rw, file = "", fill = yes;
|
||||
VIA1: start = $6000, size = $000f, 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;
|
||||
}
|
||||
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
|
||||
|
||||
.macro DEBUG_LED_OFF nr
|
||||
@ -30,18 +34,17 @@
|
||||
;********************************************************************************
|
||||
; LCD
|
||||
; .include "utility.asm6502"
|
||||
LCD_IO = IO1
|
||||
.include "system/lcd.s65"
|
||||
; LCD_IO = IO1
|
||||
.include "system/lcd.h65"
|
||||
; Keypad Reading
|
||||
KP_IO = IO2
|
||||
.include "system/keypad.s65"
|
||||
; KP_IO = IO2
|
||||
.include "system/keypad.h65"
|
||||
; SPI
|
||||
SPI_IO = IO2
|
||||
.include "system/spi.s65"
|
||||
.include "system/spi.h65"
|
||||
; Printer
|
||||
.include "programs/printer.s65"
|
||||
; .include "programs/printer.s65"
|
||||
.include "programs/print_slow.s65"
|
||||
.include "programs/spi-menu.s65"
|
||||
; .include "programs/spi-menu.s65"
|
||||
; Digital Humidity and Temerature Sensor
|
||||
; .include "dht.s65"
|
||||
|
||||
@ -54,7 +57,7 @@ IRQ_VAR: .res 1
|
||||
.code
|
||||
nmi:
|
||||
lda #'%'
|
||||
jsr lcd_char
|
||||
jsr lcd::print_char
|
||||
rti
|
||||
irq:
|
||||
; read IRFs, while bit 7 ist set handle interrupts
|
||||
@ -69,7 +72,7 @@ irq:
|
||||
bbs2 IRQ_VAR,@irq_spi_p ; check SR
|
||||
bbs1 IRQ_VAR,@irq_keypad ; check CA1
|
||||
; this should never be reached
|
||||
jsr lcd_clear
|
||||
jsr lcd::clear
|
||||
Print str_irq_unknown
|
||||
; force reset interrupt flags
|
||||
lda #$ff
|
||||
@ -77,7 +80,7 @@ irq:
|
||||
sta IO2 + IO::IFR
|
||||
bra @irq_return
|
||||
@irq_keypad:
|
||||
jsr kp_read_on_irq
|
||||
jsr kp::read_irq
|
||||
bra @irq_return
|
||||
@irq_spi_p:
|
||||
jsr spi_p::read
|
||||
@ -92,7 +95,7 @@ irq:
|
||||
; Reset sequence
|
||||
;********************************************************************************
|
||||
reset:
|
||||
jsr lcd_init
|
||||
jsr lcd::init
|
||||
|
||||
; TODO debug stuff
|
||||
stz IO2 + IO::DDRB
|
||||
@ -102,7 +105,7 @@ reset:
|
||||
DEBUG_LED_OFF 1
|
||||
|
||||
|
||||
jsr kp_init
|
||||
jsr kp::init
|
||||
|
||||
|
||||
; ; INIT DHT
|
||||
@ -124,17 +127,17 @@ reset:
|
||||
Print message_menu
|
||||
; jsr rb_keypad_read
|
||||
@loop:
|
||||
lda _KP_DEBUG_VAL
|
||||
lda kp::_DEBUG_VAL
|
||||
beq @loop
|
||||
; TODO debug
|
||||
sta 0
|
||||
stz _KP_DEBUG_VAL
|
||||
stz kp::_DEBUG_VAL
|
||||
lda 0
|
||||
; beq home
|
||||
cmp #'A'
|
||||
jeq printer
|
||||
cmp #'B'
|
||||
jeq spi_menu::spi_menu
|
||||
jeq spi_menu
|
||||
cmp #'C'
|
||||
jeq print_1
|
||||
cmp #'D'
|
||||
@ -166,23 +169,23 @@ reset:
|
||||
DEBUG_LED_ON 1
|
||||
jmp @loop
|
||||
@print_rb:
|
||||
jsr lcd_clear
|
||||
jsr lcd::clear
|
||||
Print str_io2
|
||||
lda IO2 + IO::RB
|
||||
jsr lcd_char
|
||||
jsr lcd::print_char
|
||||
lda #'''
|
||||
jsr lcd_char
|
||||
jsr lcd::print_char
|
||||
jmp @loop
|
||||
.endproc
|
||||
|
||||
|
||||
print_1:
|
||||
jsr lcd_clear
|
||||
jsr lcd::clear
|
||||
PrintSlow message_1,10
|
||||
jmp home
|
||||
|
||||
print_2:
|
||||
jsr lcd_clear
|
||||
jsr lcd::clear
|
||||
PrintSlow message_2,10
|
||||
jmp home
|
||||
|
||||
|
260
programs/dht.s65
260
programs/dht.s65
@ -1,155 +1,155 @@
|
||||
;********************************************************************************
|
||||
; @module SPI
|
||||
; @type driver
|
||||
; @details
|
||||
; @depends IO-W65C22N
|
||||
;********************************************************************************
|
||||
;;********************************************************************************
|
||||
;; @module SPI
|
||||
;; @type driver
|
||||
;; @details
|
||||
;; @depends IO-W65C22N
|
||||
;;********************************************************************************
|
||||
|
||||
;TODO EVERYTHING
|
||||
DHT_REQUEST_L = $00
|
||||
DHT_REQUEST_H = %01010000 ; = 20480 PHI2 pulses = 20,5 ms at 1 MHz
|
||||
;;TODO EVERYTHING
|
||||
;DHT_REQUEST_L = $00
|
||||
;DHT_REQUEST_H = %01010000 ; = 20480 PHI2 pulses = 20,5 ms at 1 MHz
|
||||
|
||||
DHT_RECV_H = %10011100
|
||||
DHT_RECV_L = %01000000 ; = 40000 PHI2 = 40ms
|
||||
;DHT_RECV_H = %10011100
|
||||
;DHT_RECV_L = %01000000 ; = 40000 PHI2 = 40ms
|
||||
|
||||
; Status Variables, Used to determine what is sent by temp module
|
||||
DHT_STATUS = $400
|
||||
DHT_NONE = 0
|
||||
DHT_WAIT_REQ = 1
|
||||
DHT_WAIT_RESP = 2
|
||||
DHT_RECV = 3
|
||||
DHT_DONE = 4
|
||||
;; Status Variables, Used to determine what is sent by temp module
|
||||
;DHT_STATUS = $400
|
||||
;DHT_NONE = 0
|
||||
;DHT_WAIT_REQ = 1
|
||||
;DHT_WAIT_RESP = 2
|
||||
;DHT_RECV = 3
|
||||
;DHT_DONE = 4
|
||||
|
||||
DHT_BIT = $401
|
||||
DHT_BIT_ROT = $402
|
||||
;DHT_BIT = $401
|
||||
;DHT_BIT_ROT = $402
|
||||
|
||||
|
||||
DHT_VALUES = $405 ;
|
||||
DHT_OFFSET = $403
|
||||
DHT_OFF_RH_HIGH = 0 ; offsets to DHT_VALUES
|
||||
DHT_OFF_RH_LOW = 1
|
||||
DHT_OFF_T_HIGH = 2
|
||||
DHT_OFF_T_LOW = 3
|
||||
DHT_OFF_CHECKSUM = 4
|
||||
DHT_OFF_DONE = 5
|
||||
;DHT_VALUES = $405 ;
|
||||
;DHT_OFFSET = $403
|
||||
;DHT_OFF_RH_HIGH = 0 ; offsets to DHT_VALUES
|
||||
;DHT_OFF_RH_LOW = 1
|
||||
;DHT_OFF_T_HIGH = 2
|
||||
;DHT_OFF_T_LOW = 3
|
||||
;DHT_OFF_CHECKSUM = 4
|
||||
;DHT_OFF_DONE = 5
|
||||
|
||||
|
||||
message_dht: .asciiz "DHT-Request gesendet."
|
||||
dht_wait:
|
||||
ldx #$00
|
||||
dht_wait_:
|
||||
lda message_dht,x
|
||||
sta TO_PRINT,x
|
||||
inx
|
||||
bne dht_wait_
|
||||
jsr lcd_print_clear
|
||||
dht_wait_loop: ; check after every interrpt if dht program is done and then return home
|
||||
lda #'.'
|
||||
jsr _lcd_char
|
||||
wai
|
||||
lda DHT_STATUS
|
||||
cmp #DHT_DONE
|
||||
bne dht_wait_loop
|
||||
;message_dht: .asciiz "DHT-Request gesendet."
|
||||
;dht_wait:
|
||||
; ldx #$00
|
||||
;dht_wait_:
|
||||
; lda message_dht,x
|
||||
; sta TO_PRINT,x
|
||||
; inx
|
||||
; bne dht_wait_
|
||||
; jsr lcd_print_clear
|
||||
;dht_wait_loop: ; check after every interrpt if dht program is done and then return home
|
||||
; lda #'.'
|
||||
; jsr _lcd::print_char
|
||||
; wai
|
||||
; lda DHT_STATUS
|
||||
; cmp #DHT_DONE
|
||||
; bne dht_wait_loop
|
||||
|
||||
dht_exit:
|
||||
jsr kb_read
|
||||
cmp #'*'
|
||||
jeq home
|
||||
bra dht_exit
|
||||
jmp return_home
|
||||
;dht_exit:
|
||||
; jsr kb_read
|
||||
; cmp #'*'
|
||||
; jeq home
|
||||
; bra dht_exit
|
||||
; jmp return_home
|
||||
|
||||
dht_request: ; send request to sensor
|
||||
sei
|
||||
;dht_request: ; send request to sensor
|
||||
; sei
|
||||
|
||||
lda #%00000001 ; set PA1-0 to output 0
|
||||
ora IO2 + IO_DDRA
|
||||
sta IO2 + IO_DDRA
|
||||
lda #(LCD_CLEAR | $00)
|
||||
sta IO2 + IO_RA
|
||||
; lda #%00000001 ; set PA1-0 to output 0
|
||||
; ora IO2 + IO_DDRA
|
||||
; sta IO2 + IO_DDRA
|
||||
; lda #(LCD_CLEAR | $00)
|
||||
; sta IO2 + IO_RA
|
||||
|
||||
; start timer
|
||||
lda #DHT_REQUEST_L
|
||||
sta IO2 + IO_T1CL
|
||||
lda #DHT_REQUEST_H
|
||||
sta IO2 + IO_T1CH
|
||||
; ; start timer
|
||||
; lda #DHT_REQUEST_L
|
||||
; sta IO2 + IO_T1CL
|
||||
; lda #DHT_REQUEST_H
|
||||
; sta IO2 + IO_T1CH
|
||||
|
||||
lda #DHT_WAIT_REQ
|
||||
sta DHT_STATUS
|
||||
; lda #DHT_WAIT_REQ
|
||||
; sta DHT_STATUS
|
||||
|
||||
cli
|
||||
jmp dht_wait
|
||||
; cli
|
||||
; jmp dht_wait
|
||||
|
||||
|
||||
dht_request_end:
|
||||
lda #%10000010
|
||||
sta IO2 + IO_IER ; enable Interrupt for CA1
|
||||
lda #%11111110
|
||||
and IO2 + IO_DDRA
|
||||
sta IO2 + IO_DDRA ; set PA1-0 to input
|
||||
;dht_request_end:
|
||||
; lda #%10000010
|
||||
; sta IO2 + IO_IER ; enable Interrupt for CA1
|
||||
; lda #%11111110
|
||||
; and IO2 + IO_DDRA
|
||||
; sta IO2 + IO_DDRA ; set PA1-0 to input
|
||||
|
||||
lda #DHT_WAIT_RESP
|
||||
; lda #DHT_WAIT_RESP
|
||||
|
||||
|
||||
|
||||
dht_response: ; receive response from sensor
|
||||
lda #DHT_RECV
|
||||
sta DHT_STATUS
|
||||
stz DHT_OFFSET
|
||||
lda #7
|
||||
sta DHT_BIT
|
||||
;dht_response: ; receive response from sensor
|
||||
; lda #DHT_RECV
|
||||
; sta DHT_STATUS
|
||||
; stz DHT_OFFSET
|
||||
; lda #7
|
||||
; sta DHT_BIT
|
||||
|
||||
dht_recv:
|
||||
; start timer
|
||||
lda #DHT_RECV_L
|
||||
sta IO2 + IO_T1CL
|
||||
lda #DHT_RECV_H
|
||||
sta IO2 + IO_T1CH
|
||||
rts
|
||||
;dht_recv:
|
||||
; ; start timer
|
||||
; lda #DHT_RECV_L
|
||||
; sta IO2 + IO_T1CL
|
||||
; lda #DHT_RECV_H
|
||||
; sta IO2 + IO_T1CH
|
||||
; rts
|
||||
|
||||
dht_recv_read:
|
||||
; read PA2
|
||||
lda IO2 + IO_RA
|
||||
and #%00000001
|
||||
ldx DHT_BIT
|
||||
beq dht_recv_end
|
||||
dht_recv_rot:
|
||||
rol
|
||||
dex
|
||||
bne dht_recv_rot
|
||||
dht_recv_end:
|
||||
ldy DHT_OFFSET
|
||||
ora DHT_VALUES,y
|
||||
sta DHT_VALUES,y
|
||||
; determine if 8 bits are done
|
||||
ldx DHT_BIT
|
||||
beq dht_recv_next
|
||||
rts
|
||||
dht_recv_next:
|
||||
lda #7
|
||||
sta DHT_BIT
|
||||
inc DHT_OFFSET
|
||||
cmp DHT_OFF_DONE
|
||||
beq dht_display
|
||||
rts
|
||||
;dht_recv_read:
|
||||
; ; read PA2
|
||||
; lda IO2 + IO_RA
|
||||
; and #%00000001
|
||||
; ldx DHT_BIT
|
||||
; beq dht_recv_end
|
||||
;dht_recv_rot:
|
||||
; rol
|
||||
; dex
|
||||
; bne dht_recv_rot
|
||||
;dht_recv_end:
|
||||
; ldy DHT_OFFSET
|
||||
; ora DHT_VALUES,y
|
||||
; sta DHT_VALUES,y
|
||||
; ; determine if 8 bits are done
|
||||
; ldx DHT_BIT
|
||||
; beq dht_recv_next
|
||||
; rts
|
||||
;dht_recv_next:
|
||||
; lda #7
|
||||
; sta DHT_BIT
|
||||
; inc DHT_OFFSET
|
||||
; cmp DHT_OFF_DONE
|
||||
; beq dht_display
|
||||
; rts
|
||||
|
||||
dht_display:
|
||||
ldx #0
|
||||
dht_display_:
|
||||
lda DHT_VALUES,x
|
||||
sta TO_PRINT,x
|
||||
inx
|
||||
cpx #5
|
||||
bne dht_display_
|
||||
jsr lcd_print_clear
|
||||
rts
|
||||
;dht_display:
|
||||
; ldx #0
|
||||
;dht_display_:
|
||||
; lda DHT_VALUES,x
|
||||
; sta TO_PRINT,x
|
||||
; inx
|
||||
; cpx #5
|
||||
; bne dht_display_
|
||||
; jsr lcd_print_clear
|
||||
; rts
|
||||
|
||||
dht_irq:
|
||||
lda DHT_STATUS
|
||||
cmp #DHT_WAIT_REQ
|
||||
beq dht_request_end
|
||||
cmp #DHT_WAIT_RESP
|
||||
beq dht_response
|
||||
cmp #DHT_RECV
|
||||
beq dht_recv
|
||||
rts
|
||||
;dht_irq:
|
||||
; lda DHT_STATUS
|
||||
; cmp #DHT_WAIT_REQ
|
||||
; beq dht_request_end
|
||||
; cmp #DHT_WAIT_RESP
|
||||
; beq dht_response
|
||||
; cmp #DHT_RECV
|
||||
; beq dht_recv
|
||||
; rts
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
.ifndef INCLUDE_MEMCOPY
|
||||
INCLUDE_MEMCOPY = 1
|
||||
|
||||
.include "system.h65"
|
||||
|
||||
.code
|
||||
;********************************************************************************
|
||||
; @function Copy a block of memory to a different address
|
||||
; @param ARG0-1: Source address
|
||||
@ -9,14 +11,15 @@ INCLUDE_MEMCOPY = 1
|
||||
; @param y: Number of bytes to copy
|
||||
;********************************************************************************
|
||||
.proc memcopy
|
||||
cpy
|
||||
loop:
|
||||
cpy #0
|
||||
@loop:
|
||||
beq @loop_end
|
||||
lda (ARG0),y
|
||||
sta (ARG2),y
|
||||
dey
|
||||
bra @loop
|
||||
loop_end:
|
||||
@loop_end:
|
||||
rts
|
||||
.endproc
|
||||
.endif ; guard
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
|
||||
.ifndef INCLUDE_PRINT_SLOW
|
||||
INCLUDE_PRINT_SLOW = 1
|
||||
|
||||
.include "programs/sleep.s65"
|
||||
.include "system/lcd.s65"
|
||||
|
||||
.include "system.h65"
|
||||
.include "sleep.s65"
|
||||
.include "lcd.h65"
|
||||
|
||||
.code
|
||||
;********************************************************************************
|
||||
; @function Print a null-terminated string
|
||||
; @param ARG0-1: Address of the string to print
|
||||
@ -19,7 +19,7 @@ INCLUDE_PRINT_SLOW = 1
|
||||
phx
|
||||
jsr sleep
|
||||
plx
|
||||
jsr lcd_char
|
||||
jsr lcd::print_char
|
||||
iny
|
||||
bra @print_loop
|
||||
@print_end:
|
||||
@ -32,7 +32,7 @@ INCLUDE_PRINT_SLOW = 1
|
||||
; @param time_cs: time to sleep in centiseconds
|
||||
;********************************************************************************
|
||||
.macro PrintSlow message,time_cs
|
||||
jsr lcd_clear
|
||||
jsr lcd::clear
|
||||
lda #<message
|
||||
sta ARG0
|
||||
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 @@
|
||||
;********************************************************************************
|
||||
; Printing Program
|
||||
;********************************************************************************
|
||||
.ifndef INCLUDE_PRINTER
|
||||
INCLUDE_PRINTER = 1
|
||||
.include "printer.h65"
|
||||
.include "lcd.h65"
|
||||
.include "keypad.h65"
|
||||
|
||||
.code
|
||||
printer:
|
||||
jsr lcd_clear
|
||||
.proc printer
|
||||
jsr lcd::clear
|
||||
@printer_loop:
|
||||
jsr rb_keypad_read
|
||||
jsr kp::read
|
||||
beq @printer_loop
|
||||
cmp #'*'
|
||||
jeq home
|
||||
jsr lcd_char
|
||||
jsr lcd::print_char
|
||||
bra @printer_loop
|
||||
.endif ; guard
|
||||
.endproc
|
||||
|
@ -1,5 +1,6 @@
|
||||
.ifndef INCLUDE_SLEEP
|
||||
INCLUDE_SLEEP = 1
|
||||
.include "system.h65"
|
||||
.code
|
||||
;********************************************************************************
|
||||
; @macro Sleep
|
||||
@ -20,10 +21,10 @@ INCLUDE_SLEEP = 1
|
||||
; @details
|
||||
; Interrupts might change the actual time to finish
|
||||
; To be exact, time_cs is in units of 0.010244s
|
||||
; @modifies: ARG2
|
||||
; @modifies: ARG15
|
||||
;********************************************************************************
|
||||
.proc sleep
|
||||
_VAR_1 = ARG2
|
||||
_VAR_1 = ARG15
|
||||
stz _VAR_1
|
||||
@loop:
|
||||
.repeat 17
|
||||
|
@ -1,9 +1,11 @@
|
||||
.include "system/spi.s65"
|
||||
.include "util/string.s65"
|
||||
.ifndef INCLUDE_SPI_MENU
|
||||
INCLUDE_SPI_MENU = 1
|
||||
.include "spi.h65"
|
||||
.include "string.h65"
|
||||
.include "keypad.h65"
|
||||
.include "lcd.h65"
|
||||
.import home:absolute
|
||||
.import SPI_IO
|
||||
|
||||
.scope spi_menu
|
||||
.export spi_menu
|
||||
.bss
|
||||
trans_bytes: .res 1
|
||||
trans_pages: .res 1
|
||||
@ -17,12 +19,12 @@ status_str: .res 17 ; 16 + null
|
||||
lda #'X'
|
||||
sta status
|
||||
@print_menu:
|
||||
jsr lcd_clear
|
||||
jsr lcd::clear
|
||||
Print MENU
|
||||
@print_status:
|
||||
Strf FMT_STATUS,status_str,trans_pages,trans_bytes,status
|
||||
lda #(LCD_CMD_SET_ADDRESS | LCD_LINE4)
|
||||
jsr _lcd_cmd
|
||||
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE4)
|
||||
jsr lcd::_cmd
|
||||
Print status_str
|
||||
@loop:
|
||||
; check if a byte has been transferred
|
||||
@ -43,11 +45,11 @@ status_str: .res 17 ; 16 + null
|
||||
bra @print_status
|
||||
|
||||
@read_keypad:
|
||||
lda _KP_DEBUG_VAL
|
||||
lda kp::_DEBUG_VAL
|
||||
beq @loop
|
||||
; TODO debug
|
||||
sta 0
|
||||
stz _KP_DEBUG_VAL
|
||||
stz kp::_DEBUG_VAL
|
||||
lda 0
|
||||
cmp #'*'
|
||||
beq @return_home
|
||||
@ -70,9 +72,9 @@ status_str: .res 17 ; 16 + null
|
||||
jmp @print_menu
|
||||
@spi_jump:
|
||||
jsr spi_p::end
|
||||
jsr lcd_clear
|
||||
jsr lcd::clear
|
||||
Print START
|
||||
jmp spi_p::SPI_CODE_START
|
||||
jmp spi_p::CODE_START
|
||||
@return_home:
|
||||
jsr spi_p::end
|
||||
jmp home
|
||||
@ -87,6 +89,3 @@ MENU:
|
||||
FMT_STATUS: .asciiz "%x%xb Status:%x"
|
||||
BEGIN: .asciiz "---BEGIN 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
|
||||
; @modifies: X
|
||||
;********************************************************************************
|
||||
;TODO increment read when write reaches it
|
||||
.ident(.concat(_RBUF_NAME, "_write")):
|
||||
.scope
|
||||
; 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 @@
|
||||
;********************************************************************************
|
||||
; @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
|
||||
;********************************************************************************
|
||||
.include "keypad.h65"
|
||||
|
||||
|
||||
.ifndef INCLUDE_KEYPAD
|
||||
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
|
||||
Export kp, init, read_irq, read
|
||||
ExportZp kp, _DEBUG_VAL
|
||||
|
||||
.zeropage
|
||||
_KP_COLUMN: .res 1 ; for storing stuff
|
||||
_KP_DEBUG_VAL: .res 1 ; for storing the last char DEBUG
|
||||
_COLUMN: .res 1 ; for storing stuff
|
||||
_DEBUG_VAL: .res 1 ; for storing the last char DEBUG
|
||||
|
||||
.bss ; reserve space or ringbuffer
|
||||
KP_BUF_SIZE = 10
|
||||
RBUF_MEM_START: .res KP_BUF_SIZE
|
||||
RBUF_MEM_END = RBUF_MEM_START + KP_BUF_SIZE - 1
|
||||
RBUF_MEM_START: .res kp::BUF_SIZE
|
||||
RBUF_MEM_END = RBUF_MEM_START + kp::BUF_SIZE - 1
|
||||
.define RBUF_NAME "keypad"
|
||||
.include "buffer.s65"
|
||||
.include "buffer.h65"
|
||||
|
||||
.code
|
||||
.proc kp_init
|
||||
.proc init
|
||||
; todo remove later and test
|
||||
lda #$ff
|
||||
sta KP_IO+IO::DDRA
|
||||
stz KP_IO+IO::RA
|
||||
sta kp::KP_IO+IO::DDRA
|
||||
stz kp::KP_IO+IO::RA
|
||||
|
||||
; INIT KEYPAD
|
||||
; todo: use masks
|
||||
lda #%11110000; KP_IO+IO::RA 0-3 output
|
||||
sta KP_IO+IO::DDRA
|
||||
lda #%11110000; kp::KP_IO+IO::RA 0-3 output
|
||||
sta kp::KP_IO+IO::DDRA
|
||||
; output 0, key press will pull input pin low
|
||||
stz KP_IO+IO::RA
|
||||
stz KP_IO+IO::ACR
|
||||
stz kp::KP_IO+IO::RA
|
||||
stz kp::KP_IO+IO::ACR
|
||||
|
||||
; lda #%00010000 ; set CA1 to interrupt on pos. edge
|
||||
; todo: use masks
|
||||
lda #IO::PCR::CA1_IP_AE
|
||||
sta KP_IO+IO::PCR
|
||||
sta kp::KP_IO+IO::PCR
|
||||
jsr rb_keypad_init ; init keybuffer
|
||||
lda #(IO::IRQ::IRQ | IO::IRQ::CA1) ; enable interrupt for CA1 on KP_IO
|
||||
sta KP_IO+IO::IER
|
||||
lda #(IO::IRQ::IRQ | IO::IRQ::CA1) ; enable interrupt for CA1 on kp::KP_IO
|
||||
sta kp::KP_IO+IO::IER
|
||||
rts
|
||||
.endproc
|
||||
|
||||
read = rb_keypad_read
|
||||
|
||||
;********************************************************************************
|
||||
; @function Read which key is pressed on the keypad
|
||||
; @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
|
||||
; 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
|
||||
; TODO dont check every column if the value has been found
|
||||
lda #%11100000
|
||||
@ -74,31 +62,31 @@ RBUF_MEM_END = RBUF_MEM_START + KP_BUF_SIZE - 1
|
||||
lda #%01110000
|
||||
ldx #$0c
|
||||
jsr @kp_read_column
|
||||
stz KP_IO+IO::RA
|
||||
lda KP_IO+IO::RA ; clear interrupt flag again beceause it might be set again through the above tests
|
||||
stz kp::KP_IO+IO::RA
|
||||
lda kp::KP_IO+IO::RA ; clear interrupt flag again beceause it might be set again through the above tests
|
||||
rts
|
||||
@kp_read_column:
|
||||
sta KP_IO+IO::RA
|
||||
lda KP_IO+IO::RA
|
||||
sta _KP_COLUMN ; store result in zeropage so that bbr can be used
|
||||
bbr0 _KP_COLUMN,@kp_write ; row 1
|
||||
sta kp::KP_IO+IO::RA
|
||||
lda kp::KP_IO+IO::RA
|
||||
sta _COLUMN ; store result in zeropage so that bbr can be used
|
||||
bbr0 _COLUMN,@kp_write ; row 1
|
||||
inx
|
||||
bbr1 _KP_COLUMN,@kp_write ; row 3
|
||||
bbr1 _COLUMN,@kp_write ; row 3
|
||||
inx
|
||||
bbr2 _KP_COLUMN,@kp_write ; row 2
|
||||
bbr2 _COLUMN,@kp_write ; row 2
|
||||
inx
|
||||
bbr3 _KP_COLUMN,@kp_write ; row 4
|
||||
bbr3 _COLUMN,@kp_write ; row 4
|
||||
rts
|
||||
@kp_write:
|
||||
lda _KP_VALUES,x
|
||||
lda VALUES,x
|
||||
; TODO use ringbuffer
|
||||
sta _KP_DEBUG_VAL
|
||||
sta _DEBUG_VAL
|
||||
jsr rb_keypad_write
|
||||
rts
|
||||
.endproc
|
||||
|
||||
.rodata
|
||||
_KP_VALUES:
|
||||
VALUES:
|
||||
.byte "174*"
|
||||
.byte "2850"
|
||||
.byte "396#"
|
||||
@ -108,4 +96,3 @@ _KP_VALUES:
|
||||
; row 2 = PA2
|
||||
; row 3 = PA1
|
||||
; 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 @@
|
||||
;********************************************************************************
|
||||
; @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
|
||||
.include "system/lcd.h65"
|
||||
|
||||
.ifndef LCD_IO
|
||||
.fatal "LCD_IO is not defined: set it to the base address of the IO chip of the LCD"
|
||||
.endif
|
||||
|
||||
.ifndef INCLUDE_IOW65C22
|
||||
.error "IO-W65C22 module is not included"
|
||||
.endif
|
||||
|
||||
.include "utility.h65"
|
||||
.ifndef lcd::LCD_IO
|
||||
.fatal "lcd::LCD_IO is not defined: set it to the base address of the IO chip of the LCD"
|
||||
.endif
|
||||
|
||||
Export lcd,init,clear,print,print_char,set_position
|
||||
|
||||
; RAM VARIABLES
|
||||
.ifndef LCD_MEM
|
||||
LCD_MEM = $300
|
||||
.endif
|
||||
LCD_CHARCOUNT = LCD_MEM
|
||||
.bss
|
||||
charcount: .res 1
|
||||
|
||||
; PIN MASKS
|
||||
LCD_E = %10000000
|
||||
LCD_RW = %01000000
|
||||
LCD_RS = %00100000
|
||||
; .local LCD_E,LCD_RW,LCD_RS
|
||||
|
||||
; LCD Instructions (see datasheet for more)
|
||||
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
|
||||
.code
|
||||
;;********************************************************************************
|
||||
;; @function Initialize the lcd module
|
||||
;; @details call before doing anything else
|
||||
;; @modifies A
|
||||
;;********************************************************************************
|
||||
.proc init
|
||||
; init IO
|
||||
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)
|
||||
lda #(LCD_RS | LCD_RW | LCD_E) ; RA 5-7 output
|
||||
sta LCD_IO+IO::DDRA
|
||||
; 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
|
||||
sta lcd::LCD_IO+IO::DDRA
|
||||
|
||||
; init lcd
|
||||
lda #LCD_CMD_FUNCTION_SET
|
||||
jsr _lcd_cmd
|
||||
lda #LCD_CMD_DISPLAY_ON
|
||||
jsr _lcd_cmd
|
||||
lda #LCD_CMD_CLEAR
|
||||
jsr _lcd_cmd
|
||||
lda #LCD_CMD_ENTRY_MODE
|
||||
jsr _lcd_cmd
|
||||
lda #lcd::CMD_FUNCTION_SET
|
||||
jsr _cmd
|
||||
lda #lcd::CMD_DISPLAY_ON
|
||||
jsr _cmd
|
||||
lda #lcd::CMD_CLEAR
|
||||
jsr _cmd
|
||||
lda #lcd::CMD_ENTRY_MODE
|
||||
jsr _cmd
|
||||
|
||||
stz LCD_CHARCOUNT
|
||||
stz charcount
|
||||
rts
|
||||
.endproc
|
||||
|
||||
;********************************************************************************
|
||||
; PRINTING TO LCD
|
||||
;********************************************************************************
|
||||
|
||||
;********************************************************************************
|
||||
; @function Clear the display
|
||||
; @see lcd_print
|
||||
;********************************************************************************
|
||||
.proc lcd_clear
|
||||
stz LCD_CHARCOUNT
|
||||
lda #LCD_CLEAR
|
||||
jsr _lcd_cmd
|
||||
lda #(LCD_CMD_SET_ADDRESS | LCD_LINE1)
|
||||
jsr _lcd_cmd
|
||||
|
||||
;;********************************************************************************
|
||||
;; PRINTING TO LCD
|
||||
;;********************************************************************************
|
||||
|
||||
;;********************************************************************************
|
||||
;; @function Clear the display
|
||||
;; @see lcd_print
|
||||
;; @modifies A
|
||||
;;********************************************************************************
|
||||
.proc clear
|
||||
stz charcount
|
||||
lda #lcd::CLEAR
|
||||
jsr _cmd
|
||||
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE1)
|
||||
jsr _cmd
|
||||
rts
|
||||
.endproc
|
||||
|
||||
;********************************************************************************
|
||||
; @function Print a null-terminated string
|
||||
; @param ARG0-1 Address of the string to print
|
||||
;********************************************************************************
|
||||
.proc lcd_print
|
||||
;;********************************************************************************
|
||||
;; @function Print a null-terminated string
|
||||
;; @param ARG0-1 Address of the string to print
|
||||
;; @modifies: A,Y
|
||||
;;********************************************************************************
|
||||
.proc print
|
||||
ldy #$00
|
||||
@lcd_print_loop:
|
||||
lda (ARG0),y
|
||||
beq @lcd_print_end
|
||||
jsr lcd_char
|
||||
jsr print_char
|
||||
iny
|
||||
bra @lcd_print_loop
|
||||
@lcd_print_end:
|
||||
rts
|
||||
.endproc
|
||||
|
||||
;********************************************************************************
|
||||
; @macro Print a null-terminated string
|
||||
; @param message: Address of the message
|
||||
;********************************************************************************
|
||||
.macro Print message
|
||||
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
|
||||
;;********************************************************************************
|
||||
;; @macro Print a single character
|
||||
;; @param A: Character to print
|
||||
;;********************************************************************************
|
||||
.proc print_char
|
||||
pha
|
||||
pha
|
||||
; TODO use UT_update_with_mask?
|
||||
jsr _lcd_wait_nbusy
|
||||
jsr _wait_nbusy
|
||||
pla
|
||||
sta LCD_IO + IO::RB
|
||||
lda #LCD_RS
|
||||
sta LCD_IO + IO::RA
|
||||
lda #(LCD_RS | LCD_E)
|
||||
sta LCD_IO + IO::RA
|
||||
lda #LCD_RS
|
||||
sta LCD_IO + IO::RA
|
||||
inc LCD_CHARCOUNT
|
||||
jsr _lcd_set_address
|
||||
sta lcd::LCD_IO + IO::RB
|
||||
lda #lcd::RS
|
||||
sta lcd::LCD_IO + IO::RA
|
||||
lda #(lcd::RS | lcd::E)
|
||||
sta lcd::LCD_IO + IO::RA
|
||||
lda #lcd::RS
|
||||
sta lcd::LCD_IO + IO::RA
|
||||
inc charcount
|
||||
jsr _break_line
|
||||
pla ; put char back in a
|
||||
.endproc
|
||||
|
||||
|
||||
;********************************************************************************
|
||||
; Internal LCD Commands
|
||||
;********************************************************************************
|
||||
;;********************************************************************************
|
||||
;; Internal LCD Commands
|
||||
;;********************************************************************************
|
||||
; read busy flag
|
||||
.proc _lcd_wait_nbusy
|
||||
stz LCD_IO + IO::DDRB ; set IO1-LCD_IO + IO::RB to input
|
||||
.proc _wait_nbusy
|
||||
stz lcd::LCD_IO + IO::DDRB ; set IO1-IO + IO::RB to input
|
||||
@lcd_wait_nbusy_loop: ; read the busy flag
|
||||
lda #LCD_RW
|
||||
sta LCD_IO + IO::RA
|
||||
lda #(LCD_RW | LCD_E)
|
||||
sta LCD_IO + IO::RA
|
||||
lda #lcd::RW
|
||||
sta lcd::LCD_IO + IO::RA
|
||||
lda #(lcd::RW | lcd::E)
|
||||
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
|
||||
bne @lcd_wait_nbusy_loop
|
||||
|
||||
lda #%00000000 ; TODO dont overwrite 0-4
|
||||
sta LCD_IO + IO::RA
|
||||
lda #%11111111 ; set IO1-LCD_IO + IO::RB to output
|
||||
sta LCD_IO + IO::DDRB
|
||||
sta lcd::LCD_IO + IO::RA
|
||||
lda #%11111111 ; set IO1-IO + IO::RB to output
|
||||
sta lcd::LCD_IO + IO::DDRB
|
||||
rts
|
||||
.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
|
||||
jsr _lcd_wait_nbusy
|
||||
jsr _wait_nbusy
|
||||
pla
|
||||
|
||||
; TODO use UT_update_with_mask?
|
||||
sta LCD_IO + IO::RB
|
||||
lda #LCD_CLEAR
|
||||
sta LCD_IO + IO::RA
|
||||
lda #LCD_E
|
||||
sta LCD_IO + IO::RA
|
||||
lda #LCD_CLEAR
|
||||
sta LCD_IO + IO::RA
|
||||
sta lcd::LCD_IO + IO::RB
|
||||
lda #lcd::CLEAR
|
||||
sta lcd::LCD_IO + IO::RA
|
||||
lda #lcd::E
|
||||
sta lcd::LCD_IO + IO::RA
|
||||
lda #lcd::CLEAR
|
||||
sta lcd::LCD_IO + IO::RA
|
||||
rts
|
||||
.endproc
|
||||
|
||||
|
||||
;********************************************************************************
|
||||
; Set the LCD DD-RAM Address so that text linebreaks after 16 chars
|
||||
;********************************************************************************
|
||||
.proc _lcd_set_address
|
||||
;;********************************************************************************
|
||||
;; @function Set the cursor to a position
|
||||
;; @param A: cursor position: `(lcd::LINEX + offset)`, where offset € [$0, $f]
|
||||
;; @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
|
||||
lda LCD_CHARCOUNT
|
||||
beq @lcd_line1
|
||||
lda charcount
|
||||
beq @line1
|
||||
and #%10001111 ; ($10 | $20 | $30 | $40) = %01110000
|
||||
bne @lcd_set_address_done
|
||||
bne @rts
|
||||
; checks necessary
|
||||
lda LCD_CHARCOUNT
|
||||
beq @lcd_line1
|
||||
lda charcount
|
||||
beq @line1
|
||||
cmp #$10
|
||||
beq @lcd_line2
|
||||
beq @line2
|
||||
cmp #$20
|
||||
beq @lcd_line3
|
||||
beq @line3
|
||||
cmp #$30
|
||||
beq @lcd_line4
|
||||
cmp #$40 ; set to line1 when full ; set to line1 when full
|
||||
beq @lcd_line1
|
||||
@lcd_set_address_done:
|
||||
beq @line4
|
||||
cmp #$40 ; set to line1 when full
|
||||
bge @line1
|
||||
@rts:
|
||||
rts
|
||||
@lcd_line1:
|
||||
stz LCD_CHARCOUNT
|
||||
lda #(LCD_CMD_SET_ADDRESS | LCD_LINE1)
|
||||
jsr _lcd_cmd
|
||||
@line1:
|
||||
stz charcount
|
||||
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE1)
|
||||
jsr _cmd
|
||||
rts
|
||||
@lcd_line2:
|
||||
lda #(LCD_CMD_SET_ADDRESS | LCD_LINE2)
|
||||
jsr _lcd_cmd
|
||||
@line2:
|
||||
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE2)
|
||||
jsr _cmd
|
||||
rts
|
||||
@lcd_line3:
|
||||
lda #(LCD_CMD_SET_ADDRESS | LCD_LINE3)
|
||||
jsr _lcd_cmd
|
||||
@line3:
|
||||
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE3)
|
||||
jsr _cmd
|
||||
rts
|
||||
@lcd_line4:
|
||||
lda #(LCD_CMD_SET_ADDRESS | LCD_LINE4)
|
||||
jsr _lcd_cmd
|
||||
@line4:
|
||||
lda #(lcd::CMD_SET_ADDRESS | lcd::LINE4)
|
||||
jsr _cmd
|
||||
rts
|
||||
.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 @@
|
||||
;********************************************************************************
|
||||
; @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
|
||||
.include "spi.h65"
|
||||
|
||||
Export spi_p, begin, end, read, pages_written, bytes_written
|
||||
|
||||
.zeropage
|
||||
code_page: .res 2 ; SPI_CODE_START + pages_written * 256
|
||||
code_page: .res 2 ; CODE_START + pages_written * 256
|
||||
.bss
|
||||
bytes_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
|
||||
.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
|
||||
.code
|
||||
.struct SPI_P_Pins
|
||||
@ -178,9 +39,9 @@ TEST_OUT: .asciiz "TESTOUT"
|
||||
stz pages_written
|
||||
stz bytes_written
|
||||
; store address in zp
|
||||
lda #<SPI_CODE_START
|
||||
lda #<CODE_START
|
||||
sta code_page
|
||||
lda #>SPI_CODE_START
|
||||
lda #>CODE_START
|
||||
sta code_page + 1
|
||||
; todo USE MASKS
|
||||
; set Shift register to shift in under external clock on CB1
|
||||
@ -196,6 +57,7 @@ TEST_OUT: .asciiz "TESTOUT"
|
||||
rts
|
||||
.endproc
|
||||
|
||||
|
||||
;********************************************************************************
|
||||
; @function Stop listening for SPI transfers
|
||||
; @details
|
||||
@ -209,7 +71,6 @@ TEST_OUT: .asciiz "TESTOUT"
|
||||
.endproc
|
||||
|
||||
|
||||
|
||||
;********************************************************************************
|
||||
; @function Read a byte from SPI
|
||||
; @details
|
||||
@ -218,7 +79,7 @@ TEST_OUT: .asciiz "TESTOUT"
|
||||
.proc read
|
||||
ldx bytes_written
|
||||
lda SPI_IO + IO::SR
|
||||
sta SPI_CODE_START,x
|
||||
sta CODE_START,x
|
||||
inc bytes_written
|
||||
beq @new_page
|
||||
rts
|
||||
@ -249,9 +110,3 @@ TEST_OUT: .asciiz "TESTOUT"
|
||||
;********************************************************************************
|
||||
.proc send_data
|
||||
.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 @@
|
||||
;********************************************************************************
|
||||
; @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
|
||||
.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
|
||||
.zeropage
|
||||
.org $10
|
||||
.res 16
|
||||
|
98
test.s65
98
test.s65
@ -1,55 +1,55 @@
|
||||
.include "system/system.h65"
|
||||
.segment "CODE"
|
||||
;.include "system/system.h65"
|
||||
;.segment "CODE"
|
||||
|
||||
;********************************************************************************
|
||||
; Interrupts
|
||||
;********************************************************************************
|
||||
nmi:
|
||||
rti
|
||||
irq:
|
||||
.repeat 20
|
||||
.endrepeat
|
||||
rti
|
||||
;;********************************************************************************
|
||||
;; Interrupts
|
||||
;;********************************************************************************
|
||||
;nmi:
|
||||
; rti
|
||||
;irq:
|
||||
; .repeat 20
|
||||
; .endrepeat
|
||||
; rti
|
||||
|
||||
;********************************************************************************
|
||||
; Reset sequence
|
||||
;********************************************************************************
|
||||
reset:
|
||||
sei
|
||||
; setup io2 bank a 1-3
|
||||
lda #%11111111
|
||||
sta IO1 + IO_DDRA
|
||||
sta IO1 + IO_DDRB
|
||||
;;********************************************************************************
|
||||
;; Reset sequence
|
||||
;;********************************************************************************
|
||||
;reset:
|
||||
; sei
|
||||
; ; setup io2 bank a 1-3
|
||||
; lda #%11111111
|
||||
; sta IO1 + IO_DDRA
|
||||
; sta IO1 + IO_DDRB
|
||||
|
||||
@loop:
|
||||
lda #%00000000
|
||||
sta IO1 + IO_RA
|
||||
.repeat 3
|
||||
nop
|
||||
.endrepeat
|
||||
lda #%11111111
|
||||
sta IO1 + IO_RA
|
||||
.repeat 15
|
||||
nop
|
||||
.endrepeat
|
||||
;@loop:
|
||||
; lda #%00000000
|
||||
; sta IO1 + IO_RA
|
||||
; .repeat 3
|
||||
; nop
|
||||
; .endrepeat
|
||||
; lda #%11111111
|
||||
; sta IO1 + IO_RA
|
||||
; .repeat 15
|
||||
; nop
|
||||
; .endrepeat
|
||||
|
||||
lda #%00000000
|
||||
sta IO1 + IO_RB
|
||||
.repeat 5
|
||||
nop
|
||||
.endrepeat
|
||||
lda #%11111111
|
||||
sta IO1 + IO_RB
|
||||
.repeat 10
|
||||
nop
|
||||
.endrepeat
|
||||
bra @loop
|
||||
; lda #%00000000
|
||||
; sta IO1 + IO_RB
|
||||
; .repeat 5
|
||||
; nop
|
||||
; .endrepeat
|
||||
; lda #%11111111
|
||||
; sta IO1 + IO_RB
|
||||
; .repeat 10
|
||||
; nop
|
||||
; .endrepeat
|
||||
; bra @loop
|
||||
|
||||
;********************************************************************************
|
||||
; reset vector
|
||||
;********************************************************************************
|
||||
.segment "RESET_VECTOR"
|
||||
.word nmi
|
||||
.word reset
|
||||
.word irq
|
||||
;;********************************************************************************
|
||||
;; reset vector
|
||||
;;********************************************************************************
|
||||
;.segment "RESET_VECTOR"
|
||||
; .word nmi
|
||||
; .word reset
|
||||
; .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 @@
|
||||
;********************************************************************************
|
||||
; @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
|
||||
.code
|
||||
|
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 @@
|
||||
;********************************************************************************
|
||||
; @module string
|
||||
; @type utility
|
||||
; @details
|
||||
; String utility
|
||||
;********************************************************************************
|
||||
.ifndef INCLUDE_STRING
|
||||
INCLUDE_STRING = 1
|
||||
|
||||
.scope str
|
||||
.include "string.h65"
|
||||
.include "math.h65"
|
||||
Export str, strf, int8_to_hex_str
|
||||
|
||||
.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
|
||||
; @details
|
||||
@ -73,6 +18,8 @@ out_idx = $31
|
||||
; @returns
|
||||
; @modifies: A, X, Y
|
||||
;********************************************************************************
|
||||
out_idx := str::out_idx
|
||||
fmt_idx := str::fmt_idx
|
||||
.proc strf
|
||||
stz out_idx
|
||||
stz fmt_idx
|
||||
@ -156,8 +103,3 @@ out_idx = $31
|
||||
.rodata
|
||||
HEX_CHARS_UPPER: .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
|
||||
|
||||
.macpack longbranch ; jeq, jge...
|
||||
.macpack generic ; bge, add, sub
|
||||
|
||||
;********************************************************************************
|
||||
; @macro Update a byte in memory using a mask
|
||||
@ -31,4 +32,59 @@ INCLUDE_UTILITY = 1
|
||||
; _n_genlabel .set _n_genlabel + 1
|
||||
;.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
|
||||
|
Loading…
Reference in New Issue
Block a user