Compare commits
No commits in common. "302e49a9f79f8e2255b6227e7c3bf23c7f924c19" and "25d0fcfb9016f60523f89c2d2dad4a39df60088c" have entirely different histories.
302e49a9f7
...
25d0fcfb90
@ -7,7 +7,6 @@ MEMORY {
|
|||||||
VIA1: start = $6000, size = $000f, 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;
|
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;
|
||||||
TEST: start = $9000, size = $1000, type = rw, file = "../test.bin";
|
|
||||||
}
|
}
|
||||||
SEGMENTS {
|
SEGMENTS {
|
||||||
VIA1: load = VIA1, type = bss;
|
VIA1: load = VIA1, type = bss;
|
||||||
@ -17,6 +16,5 @@ SEGMENTS {
|
|||||||
CODE: load = ROM, type = ro;
|
CODE: load = ROM, type = ro;
|
||||||
RODATA: load = ROM, type = ro;
|
RODATA: load = ROM, type = ro;
|
||||||
RESET_VECTOR: load = ROM, type = ro, start = $FFFA;
|
RESET_VECTOR: load = ROM, type = ro, start = $FFFA;
|
||||||
SPI: load = SPI, type = rw, define = yes;
|
SPI: load = SPI, type = rw;
|
||||||
TEST: load = TEST,type = rw;
|
|
||||||
}
|
}
|
||||||
|
20
main.s65
20
main.s65
@ -65,7 +65,7 @@ irq:
|
|||||||
@irq_io1:
|
@irq_io1:
|
||||||
lda IO1 + IO::IFR
|
lda IO1 + IO::IFR
|
||||||
sta irq_via_ifr
|
sta irq_via_ifr
|
||||||
bbr7 irq_via_ifr,@irq_io1 ; skip
|
bbr7 irq_via_ifr,@irq_io2 ; skip
|
||||||
bbs2 irq_via_ifr,@irq_kb1 ; shit reg -> first 8 bits
|
bbs2 irq_via_ifr,@irq_kb1 ; shit reg -> first 8 bits
|
||||||
bbs5 irq_via_ifr,@irq_kb2 ; timer -> last 3 bits
|
bbs5 irq_via_ifr,@irq_kb2 ; timer -> last 3 bits
|
||||||
@irq_io2:
|
@irq_io2:
|
||||||
@ -74,7 +74,6 @@ irq:
|
|||||||
bbr7 irq_via_ifr,@irq_return ; skip
|
bbr7 irq_via_ifr,@irq_return ; skip
|
||||||
bbs2 irq_via_ifr,@irq_spi_p ; check SR
|
bbs2 irq_via_ifr,@irq_spi_p ; check SR
|
||||||
bbs1 irq_via_ifr,@irq_keypad ; check CA1
|
bbs1 irq_via_ifr,@irq_keypad ; check CA1
|
||||||
|
|
||||||
; this SHOULD never be reached
|
; this SHOULD never be reached
|
||||||
jsr lcd::clear
|
jsr lcd::clear
|
||||||
Print "Unknown IRQ"
|
Print "Unknown IRQ"
|
||||||
@ -82,18 +81,23 @@ irq:
|
|||||||
lda #$ff
|
lda #$ff
|
||||||
sta IO1 + IO::IFR
|
sta IO1 + IO::IFR
|
||||||
sta IO2 + IO::IFR
|
sta IO2 + IO::IFR
|
||||||
bra @irq_return
|
rti
|
||||||
|
; bra @irq_return
|
||||||
@irq_keypad:
|
@irq_keypad:
|
||||||
jsr kp::read_irq
|
lda #<@irq_return
|
||||||
bra @irq_return
|
pha
|
||||||
|
lda #>@irq_return
|
||||||
|
pha
|
||||||
|
jmp (spi_p::irq_handler)
|
||||||
@irq_spi_p:
|
@irq_spi_p:
|
||||||
JsrIndirect (spi_p::irq_handler), @irq_return
|
jsr spi_p::read
|
||||||
|
bra @irq_return
|
||||||
@irq_kb1:
|
@irq_kb1:
|
||||||
Print "$3000"
|
; PrintNC "<30>"
|
||||||
jsr $3000
|
jsr $3000
|
||||||
bra @irq_return
|
bra @irq_return
|
||||||
@irq_kb2:
|
@irq_kb2:
|
||||||
Print "$3100"
|
; PrintNC "<31>"
|
||||||
jsr $3100
|
jsr $3100
|
||||||
bra @irq_return
|
bra @irq_return
|
||||||
; @irq_dht:
|
; @irq_dht:
|
||||||
|
@ -3,16 +3,15 @@ INCLUDE_MEMCOPY = 1
|
|||||||
|
|
||||||
.include "system.h65"
|
.include "system.h65"
|
||||||
|
|
||||||
.export memcopy,memcopy16
|
.export memcopy
|
||||||
|
|
||||||
.code
|
.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
|
||||||
;; @param ARG2-3: Target address
|
; @param ARG2-3: Target address
|
||||||
;; @param Y: Number of bytes to copy
|
; @param y: Number of bytes to copy
|
||||||
;; @modifies: A,Y
|
;********************************************************************************
|
||||||
;;********************************************************************************
|
|
||||||
.proc memcopy
|
.proc memcopy
|
||||||
cpy #0
|
cpy #0
|
||||||
beq @rts
|
beq @rts
|
||||||
@ -25,41 +24,5 @@ INCLUDE_MEMCOPY = 1
|
|||||||
@rts:
|
@rts:
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
;;********************************************************************************
|
|
||||||
;; @function Copy a block of memory to a different address
|
|
||||||
;; @param ARG0-1: Source address
|
|
||||||
;; @param ARG2-3: Target address
|
|
||||||
;; @param ARG5-6: Number of bytes to copy (LE)
|
|
||||||
;; @modifies: A,Y
|
|
||||||
;;********************************************************************************
|
|
||||||
.proc memcopy16
|
|
||||||
lda ARG6
|
|
||||||
beq @last_page ; no full page
|
|
||||||
ldy #$ff
|
|
||||||
bra @copy_byte
|
|
||||||
@next_page: ; y is 0
|
|
||||||
lda ARG6
|
|
||||||
beq @rts ; done
|
|
||||||
inc ARG1
|
|
||||||
inc ARG3
|
|
||||||
dec ARG6
|
|
||||||
beq @last_page
|
|
||||||
ldy #$ff
|
|
||||||
@copy_byte:
|
|
||||||
lda (ARG0),y
|
|
||||||
sta (ARG2),y
|
|
||||||
@dec_y:
|
|
||||||
dey
|
|
||||||
beq @next_page
|
|
||||||
bra @copy_byte
|
|
||||||
@last_page:
|
|
||||||
ldy ARG5
|
|
||||||
dey
|
|
||||||
bra @copy_byte
|
|
||||||
@rts:
|
|
||||||
rts
|
|
||||||
.endproc
|
|
||||||
|
|
||||||
.endif ; guard
|
.endif ; guard
|
||||||
|
|
||||||
|
@ -4,56 +4,43 @@
|
|||||||
.include "lcd.h65"
|
.include "lcd.h65"
|
||||||
.include "chars.h65"
|
.include "chars.h65"
|
||||||
.import home:absolute
|
.import home:absolute
|
||||||
.import CODE_START: absolute
|
.import SPI_IO
|
||||||
.import __SPI_SIZE__
|
|
||||||
|
|
||||||
.export spi_menu
|
.export spi_menu
|
||||||
.bss
|
.bss
|
||||||
trans_bytes: .res 2 ; used to check if screen needs to be updated
|
trans_bytes: .res 1
|
||||||
status_char: .res 1
|
trans_pages: .res 1
|
||||||
|
status: .res 1
|
||||||
status_str: .res 17 ; 16 + null
|
status_str: .res 17 ; 16 + null
|
||||||
|
|
||||||
.code
|
.code
|
||||||
.proc spi_menu
|
.proc spi_menu
|
||||||
stz trans_bytes
|
stz trans_bytes
|
||||||
stz trans_bytes+1
|
stz trans_pages
|
||||||
|
lda #'X'
|
||||||
|
sta status
|
||||||
@print_menu:
|
@print_menu:
|
||||||
jsr lcd::clear
|
jsr lcd::clear
|
||||||
Print MENU
|
Print MENU
|
||||||
|
|
||||||
@update_status:
|
|
||||||
lda spi_p::status
|
|
||||||
cmp #spi_p::STATUS::ERROR
|
|
||||||
beq @status_ERROR
|
|
||||||
cmp #spi_p::STATUS::DONE
|
|
||||||
beq @status_DONE
|
|
||||||
bra @status_XFER
|
|
||||||
@status_ERROR:
|
|
||||||
lda #'E'
|
|
||||||
bra @update_status_end
|
|
||||||
@status_DONE:
|
|
||||||
lda #'O'
|
|
||||||
bra @update_status_end
|
|
||||||
@status_XFER:
|
|
||||||
lda #'X'
|
|
||||||
@update_status_end:
|
|
||||||
sta status_char
|
|
||||||
|
|
||||||
@print_status:
|
@print_status:
|
||||||
lda #lcd::LINE4
|
lda #lcd::LINE4
|
||||||
jsr lcd::set_position
|
jsr lcd::set_position
|
||||||
Strf "%x%xb Status: %c",status_str,trans_bytes+1,trans_bytes,status_char
|
Strf FMT_STATUS,status_str,trans_pages,trans_bytes,status
|
||||||
PrintNC status_str
|
PrintNC status_str
|
||||||
@loop:
|
@loop:
|
||||||
; check if a byte has been transferred
|
; check if a byte has been transferred
|
||||||
@check_received:
|
@check_byte:
|
||||||
lda spi_p::recv_bytes
|
lda spi_p::bytes_written
|
||||||
cmp trans_bytes
|
cmp trans_bytes
|
||||||
beq @read_keypad
|
beq @read_keypad
|
||||||
@byte_received:
|
@byte_written:
|
||||||
sta trans_bytes
|
sta trans_bytes
|
||||||
lda spi_p::recv_bytes+1
|
@check_page:
|
||||||
lda trans_bytes+1
|
lda spi_p::pages_written
|
||||||
|
cmp trans_pages
|
||||||
|
beq @read_keypad
|
||||||
|
@page_written:
|
||||||
|
sta trans_pages
|
||||||
bra @print_status
|
bra @print_status
|
||||||
@read_keypad:
|
@read_keypad:
|
||||||
lda kp::_DEBUG_VAL
|
lda kp::_DEBUG_VAL
|
||||||
@ -70,26 +57,22 @@ status_str: .res 17 ; 16 + null
|
|||||||
beq @spi_end
|
beq @spi_end
|
||||||
cmp #'C'
|
cmp #'C'
|
||||||
beq @spi_jump
|
beq @spi_jump
|
||||||
bra @update_status ; any other key
|
bra @loop
|
||||||
@spi_begin:
|
@spi_begin:
|
||||||
lda #<CODE_START
|
lda #'@'
|
||||||
sta ARG0
|
sta status
|
||||||
lda #>CODE_START
|
jsr spi_p::begin
|
||||||
sta ARG1
|
|
||||||
lda #<__SPI_SIZE__
|
|
||||||
sta ARG2
|
|
||||||
lda #>__SPI_SIZE__
|
|
||||||
sta ARG3
|
|
||||||
jsr spi_p::begin_read
|
|
||||||
jmp @print_menu
|
jmp @print_menu
|
||||||
@spi_end:
|
@spi_end:
|
||||||
|
lda #'X'
|
||||||
|
sta status
|
||||||
jsr spi_p::end
|
jsr spi_p::end
|
||||||
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 CODE_START
|
jmp spi_p::CODE_START
|
||||||
@return_home:
|
@return_home:
|
||||||
jsr spi_p::end
|
jsr spi_p::end
|
||||||
jmp home
|
jmp home
|
||||||
|
26
spicode.s65
26
spicode.s65
@ -3,7 +3,6 @@
|
|||||||
.include "lcd.h65"
|
.include "lcd.h65"
|
||||||
.include "math.h65"
|
.include "math.h65"
|
||||||
.include "keypad.h65"
|
.include "keypad.h65"
|
||||||
.include "keyboard.h65"
|
|
||||||
.include "chars.h65"
|
.include "chars.h65"
|
||||||
.import homeloop:absolute
|
.import homeloop:absolute
|
||||||
.import home:absolute
|
.import home:absolute
|
||||||
@ -13,6 +12,9 @@
|
|||||||
|
|
||||||
.import memcopy
|
.import memcopy
|
||||||
|
|
||||||
|
.scope kb
|
||||||
|
KB_IO = IO1
|
||||||
|
.endscope
|
||||||
|
|
||||||
|
|
||||||
CODE_START:
|
CODE_START:
|
||||||
@ -58,7 +60,7 @@ CODE_START:
|
|||||||
|
|
||||||
; PrintNC $3000
|
; PrintNC $3000
|
||||||
|
|
||||||
jsr kb::init
|
jsr kbinit
|
||||||
|
|
||||||
lda #'%'
|
lda #'%'
|
||||||
jsr lcd::print_char
|
jsr lcd::print_char
|
||||||
@ -108,7 +110,7 @@ CODE_START:
|
|||||||
jsr lcd::print_char
|
jsr lcd::print_char
|
||||||
bra @loop
|
bra @loop
|
||||||
@lB:
|
@lB:
|
||||||
Strf fmt_str, out_str, kb::keycode
|
Strf fmt_str, out_str, keycode
|
||||||
Print out_str
|
Print out_str
|
||||||
bra @loop
|
bra @loop
|
||||||
@lC:
|
@lC:
|
||||||
@ -166,11 +168,11 @@ CODE_START:
|
|||||||
; .endproc
|
; .endproc
|
||||||
|
|
||||||
|
|
||||||
.proc irq_timer_handler
|
.proc irq_on_timer
|
||||||
; lda #'<'
|
; lda #'<'
|
||||||
; jsr lcd::print_char
|
; jsr lcd::print_char
|
||||||
lda kb::KB_IO + IO::SR
|
lda kb::KB_IO + IO::SR
|
||||||
sta kb::key_read + 1
|
sta key_read + 1
|
||||||
|
|
||||||
lda kb::KB_IO + IO::T2CL ; clear interrupt flag
|
lda kb::KB_IO + IO::T2CL ; clear interrupt flag
|
||||||
|
|
||||||
@ -188,16 +190,16 @@ CODE_START:
|
|||||||
ror
|
ror
|
||||||
ror
|
ror
|
||||||
ror
|
ror
|
||||||
lda kb::key_read ; not affecting carry
|
lda key_read ; not affecting carry
|
||||||
rol ; rotate carry into byte, rotate startbit into carry
|
rol ; rotate carry into byte, rotate startbit into carry
|
||||||
; TODO byte is inverted, maybe consider wasting 256 bytes for a bit reverse lookup table?
|
; TODO byte is inverted, maybe consider wasting 256 bytes for a bit reverse lookup table?
|
||||||
sta kb::keycode
|
sta keycode
|
||||||
|
|
||||||
Strf fmt_str2, out_str, kb::keycode, kb::key_read, kb::key_read+1
|
Strf fmt_str2, out_str, keycode, key_read, key_read+1
|
||||||
PrintNC out_str
|
PrintNC out_str
|
||||||
|
|
||||||
stz kb::key_read
|
stz key_read
|
||||||
stz kb::key_read+1
|
stz key_read+1
|
||||||
|
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
@ -207,7 +209,7 @@ CODE_START:
|
|||||||
kb_irq1:
|
kb_irq1:
|
||||||
; lda #'!'
|
; lda #'!'
|
||||||
; jsr lcd::print_char
|
; jsr lcd::print_char
|
||||||
jsr kb::irq_shift_reg_handler
|
jsr kb::on_shift_reg_irq
|
||||||
; lda #':'
|
; lda #':'
|
||||||
; jsr lcd::print_char
|
; jsr lcd::print_char
|
||||||
rts
|
rts
|
||||||
@ -216,7 +218,7 @@ kb_irq2:
|
|||||||
; lda #'?'
|
; lda #'?'
|
||||||
; jsr lcd::print_char
|
; jsr lcd::print_char
|
||||||
; jsr kb::on_timer_irq
|
; jsr kb::on_timer_irq
|
||||||
jsr irq_timer_handler
|
jsr irq_on_timer
|
||||||
; lda #';'
|
; lda #';'
|
||||||
; jsr lcd::print_char
|
; jsr lcd::print_char
|
||||||
rts
|
rts
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
;;********************************************************************************
|
;********************************************************************************
|
||||||
;; @module irq_handler
|
; @module irq_handler
|
||||||
;; @type system
|
; @type system
|
||||||
;;********************************************************************************
|
;********************************************************************************
|
||||||
.ifndef INCLUDE_IRQ_HANDLER
|
.ifndef INCLUDE_IRQ_HANDLER
|
||||||
INCLUDE_IRQ_HANDLER = 1
|
INCLUDE_IRQ_HANDLER = 1
|
||||||
|
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
;;********************************************************************************
|
|
||||||
;; @module keyboard
|
|
||||||
;; @type drive
|
|
||||||
;; @details:
|
|
||||||
;; Support for a PS2 Keyboard using the shift register of a 6522 VIA
|
|
||||||
;; Pressing a key causes 11 bits to be sent: 1 start - 8 keycode - 1 parity - 1 stop
|
|
||||||
;; The VIA is set up to interrupt after 8 bits have been shifted into the shift register
|
|
||||||
;; from the external clock pulses of the keyboard (additional hardware required to
|
|
||||||
;; address the hardware bug of the VIA, where bit get lost when the external clock
|
|
||||||
;; transition happens during falling edge of PHI2). After reading the shift register,
|
|
||||||
;; the VIAs T2 timer is set to interrupt after the last 3 bits have been shifted in,
|
|
||||||
;; which takes about ~230ms.
|
|
||||||
;;********************************************************************************
|
|
||||||
.ifndef INCLUDE_KEYBOARD
|
|
||||||
INCLUDE_KEYBOARD = 1
|
|
||||||
.include "system.h65"
|
|
||||||
|
|
||||||
.scope kb
|
|
||||||
Import kb,init,irq_shift_reg_handler,irq_timer_handler,keycode,key_read
|
|
||||||
KB_IO = IO1
|
|
||||||
|
|
||||||
.endscope
|
|
||||||
.endif
|
|
@ -1,106 +0,0 @@
|
|||||||
.include "keyboard.h65"
|
|
||||||
.include "string.h65"
|
|
||||||
.include "lcd.h65"
|
|
||||||
Export kb,init,irq_shift_reg_handler,irq_timer_handler,keycode,key_read
|
|
||||||
|
|
||||||
.bss
|
|
||||||
key_read: .res 2
|
|
||||||
keycode: .res 1
|
|
||||||
|
|
||||||
.code
|
|
||||||
;;********************************************************************************
|
|
||||||
;; @function Initialize the PS2 keyboard
|
|
||||||
;; @modifies: A
|
|
||||||
;;********************************************************************************
|
|
||||||
.proc init
|
|
||||||
; - use the shift register interrupts to read the first 8 bits
|
|
||||||
; set shift register to shift in under external clock on CB1
|
|
||||||
; - configure timer for timing the read of the last 3 bits
|
|
||||||
; timer 2 one shot mode is sufficient, leaves T1 available
|
|
||||||
lda #(IO::ACR::SR_SIN_PHIE | IO::ACR::T2_IRQ_LOAD)
|
|
||||||
tsb kb::KB_IO + IO::ACR
|
|
||||||
; the 3 last bits take about 230us, at @1MHz => wait 230 cycles and then the shift register
|
|
||||||
; (this could be shorter since the it takes a few cycles after the interrupt)
|
|
||||||
lda #230
|
|
||||||
sta kb::KB_IO + IO::T2CL
|
|
||||||
stz key_read
|
|
||||||
stz key_read+1
|
|
||||||
|
|
||||||
; enable SR interrupts
|
|
||||||
lda #(IO::IRQ::IRQ | IO::IRQ::SR)
|
|
||||||
sta kb::KB_IO + IO::IER
|
|
||||||
; load SR to reset
|
|
||||||
lda kb::KB_IO + IO::SR
|
|
||||||
rts
|
|
||||||
.endproc
|
|
||||||
|
|
||||||
|
|
||||||
;;********************************************************************************
|
|
||||||
;; @function Read the first 8 bits an
|
|
||||||
;; @modifies: A
|
|
||||||
;; @details
|
|
||||||
;; - read shift register
|
|
||||||
;; - disable shift register interrupts
|
|
||||||
;; - reset shift register
|
|
||||||
;; - enable timer 2 interrupts
|
|
||||||
;; - start timer 2
|
|
||||||
;; IO::SR has to be read before the next bit is shifted in, which happens ~75us after the irq
|
|
||||||
;; at 1MHz, handling this interrupt takes about 50us (without any additional debug code),
|
|
||||||
;; so it should work
|
|
||||||
;;********************************************************************************
|
|
||||||
.proc irq_shift_reg_handler
|
|
||||||
lda kb::KB_IO + IO::SR
|
|
||||||
sta key_read
|
|
||||||
stz kb::KB_IO + IO::SR
|
|
||||||
|
|
||||||
; disable SR interrupts
|
|
||||||
lda #IO::IRQ::SR
|
|
||||||
sta kb::KB_IO + IO::IER
|
|
||||||
; enable timer interrupts
|
|
||||||
lda #(IO::IRQ::IRQ | IO::IRQ::T2)
|
|
||||||
sta kb::KB_IO + IO::IER
|
|
||||||
; start timer, low order count already in latch after init
|
|
||||||
lda #1
|
|
||||||
sta kb::KB_IO + IO::T2CH
|
|
||||||
rts
|
|
||||||
.endproc
|
|
||||||
|
|
||||||
|
|
||||||
;;********************************************************************************
|
|
||||||
;; @function Read the last 3 bits after after timer 2 is up
|
|
||||||
;; @modifies: A
|
|
||||||
;; @details
|
|
||||||
;; - read shift register
|
|
||||||
;; - disable timer 2 interrupts
|
|
||||||
;; - enable shift register interrupts
|
|
||||||
;; - reset shift register
|
|
||||||
;;********************************************************************************
|
|
||||||
.proc irq_timer_handler
|
|
||||||
lda kb::KB_IO + IO::SR
|
|
||||||
sta key_read + 1
|
|
||||||
|
|
||||||
lda kb::KB_IO + IO::T2CL ; clear interrupt flag
|
|
||||||
|
|
||||||
; disable timer interrupts
|
|
||||||
lda #(IO::IRQ::T2)
|
|
||||||
sta kb::KB_IO + IO::IER
|
|
||||||
; enable shift register interrupts
|
|
||||||
lda #(IO::IRQ::IRQ | IO::IRQ::SR)
|
|
||||||
sta kb::KB_IO + IO::IER
|
|
||||||
; reset SR
|
|
||||||
stz kb::KB_IO + IO::SR
|
|
||||||
|
|
||||||
; rotate bit 2 (last bit of keycode) into the carry
|
|
||||||
lda key_read+1
|
|
||||||
ror
|
|
||||||
ror
|
|
||||||
ror
|
|
||||||
lda key_read ; not affecting carry
|
|
||||||
rol ; rotate carry into byte, rotate startbit into carry
|
|
||||||
; TODO byte is inverted, maybe consider wasting 256 bytes for a bit reverse lookup table?
|
|
||||||
sta keycode
|
|
||||||
|
|
||||||
stz key_read
|
|
||||||
stz key_read+1
|
|
||||||
rts
|
|
||||||
.endproc
|
|
@ -22,7 +22,7 @@ charcount: .res 1
|
|||||||
lda #$ff ; RB 0-7 output
|
lda #$ff ; RB 0-7 output
|
||||||
sta lcd::LCD_IO+IO::DDRB
|
sta lcd::LCD_IO+IO::DDRB
|
||||||
|
|
||||||
MaskedWrite lcd::LCD_IO+IO::DDRA, #(lcd::RS | lcd::RW | lcd::E), #lcd::RA_MASK
|
MaskedWrite lcd::LCD_IO+IO::DDRA, (lcd::RS | lcd::RW | lcd::E), lcd::RA_MASK
|
||||||
; lda #(lcd::RS | lcd::RW | lcd::E) ; RA 5-7 output
|
; lda #(lcd::RS | lcd::RW | lcd::E) ; RA 5-7 output
|
||||||
; sta lcd::LCD_IO+IO::DDRA
|
; sta lcd::LCD_IO+IO::DDRA
|
||||||
|
|
||||||
|
@ -12,9 +12,7 @@ INCLUDE_SPI = 1
|
|||||||
|
|
||||||
.scope spi_p
|
.scope spi_p
|
||||||
SPI_IO = IO2
|
SPI_IO = IO2
|
||||||
Import spi_p, irq_handler, end, status
|
Import spi_p, begin_read, irq_read_byte, begin_write, irq_write_byte, end, recv_bytes, sent_bytes, status
|
||||||
Import spi_p, begin_read, irq_read_byte, recv_bytes
|
|
||||||
Import spi_p, begin_write, irq_write_byte, sent_bytes
|
|
||||||
|
|
||||||
.enum STATUS
|
.enum STATUS
|
||||||
XFER_SIZEL = %10000000
|
XFER_SIZEL = %10000000
|
||||||
@ -26,17 +24,3 @@ Import spi_p, begin_write, irq_write_byte, sent_bytes
|
|||||||
|
|
||||||
.endscope
|
.endscope
|
||||||
.endif ; guard
|
.endif ; guard
|
||||||
|
|
||||||
; .struct SPI_P_Pins
|
|
||||||
; ; VIA addresses
|
|
||||||
; DDR_a .word ; address of the data direction register
|
|
||||||
; R_a .word ; address of the register
|
|
||||||
; ; pin mask
|
|
||||||
; SCLK_p .byte ; Serial Clock
|
|
||||||
; POCI_p .byte ; Peripheral Out / Controller In
|
|
||||||
; PICO_p .byte ; Peripheral In / Controller Out
|
|
||||||
; CSB_p .byte ; Chip Select
|
|
||||||
; ; settings
|
|
||||||
; CPOL .byte ; Clock Polarity
|
|
||||||
; CPHA .byte ; Clock Phase
|
|
||||||
; .endstruct
|
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
.include "spi.h65"
|
.include "spi.h65"
|
||||||
.include "system.h65"
|
|
||||||
|
|
||||||
Export spi_p, irq_handler, end, status
|
Export spi_p, begin_read, irq_read_byte, begin_write, irq_write_byte, end, recv_bytes, sent_bytes, status, spi_irq
|
||||||
Export spi_p, begin_read, irq_read_byte, recv_bytes
|
|
||||||
Export spi_p, begin_write, irq_write_byte, sent_bytes
|
|
||||||
|
|
||||||
.zeropage
|
.zeropage
|
||||||
buffer_start: .res 2
|
buffer_start: .res 2
|
||||||
@ -20,14 +17,19 @@ SPI_IO := spi_p::SPI_IO
|
|||||||
; spi-transferred code will be placed here
|
; spi-transferred code will be placed here
|
||||||
; SPI_P = as peripheral
|
; SPI_P = as peripheral
|
||||||
.code
|
.code
|
||||||
|
; .struct SPI_P_Pins
|
||||||
;;********************************************************************************
|
; ; VIA addresses
|
||||||
;; @function Begin listening for SPI transfers
|
; DDR_a .word ; address of the data direction register
|
||||||
;;********************************************************************************
|
; R_a .word ; address of the register
|
||||||
.proc init
|
; ; pin mask
|
||||||
lda #spi_p::STATUS::DONE
|
; SCLK_p .byte ; Serial Clock
|
||||||
sta status
|
; POCI_p .byte ; Peripheral Out / Controller In
|
||||||
.endproc
|
; PICO_p .byte ; Peripheral In / Controller Out
|
||||||
|
; CSB_p .byte ; Chip Select
|
||||||
|
; ; settings
|
||||||
|
; CPOL .byte ; Clock Polarity
|
||||||
|
; CPHA .byte ; Clock Phase
|
||||||
|
; .endstruct
|
||||||
|
|
||||||
|
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
@ -46,7 +48,7 @@ SPI_IO := spi_p::SPI_IO
|
|||||||
.proc begin_read
|
.proc begin_read
|
||||||
stz recv_bytes
|
stz recv_bytes
|
||||||
stz recv_bytes+1
|
stz recv_bytes+1
|
||||||
lda #spi_p::STATUS::XFER_SIZEL
|
lda #%spi_p::STATUS::XFER_SIZEL
|
||||||
sta status
|
sta status
|
||||||
|
|
||||||
; store address in zp
|
; store address in zp
|
||||||
@ -184,7 +186,7 @@ SPI_IO := spi_p::SPI_IO
|
|||||||
; write the first byte
|
; write the first byte
|
||||||
@write_size1:
|
@write_size1:
|
||||||
lda buffer_size
|
lda buffer_size
|
||||||
sta SPI_IO+IO::SR
|
sta SPI_IO+IO_SR
|
||||||
lda #spi_p::STATUS::XFER_SIZEH
|
lda #spi_p::STATUS::XFER_SIZEH
|
||||||
sta status
|
sta status
|
||||||
rts
|
rts
|
||||||
@ -234,9 +236,11 @@ SPI_IO := spi_p::SPI_IO
|
|||||||
rts
|
rts
|
||||||
@write_size2:
|
@write_size2:
|
||||||
lda buffer_size+1
|
lda buffer_size+1
|
||||||
sta SPI_IO+IO::SR
|
sta SPI_IO+IO_SR
|
||||||
lda #spi_p::STATUS::XFER
|
lda #spi_p::STATUS::XFER
|
||||||
sta status
|
sta status
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
|
.endproc
|
||||||
|
@ -8,57 +8,43 @@
|
|||||||
.ifndef INCLUDE_SYSTEM
|
.ifndef INCLUDE_SYSTEM
|
||||||
INCLUDE_SYSTEM = 1
|
INCLUDE_SYSTEM = 1
|
||||||
; reserved RAM addresses
|
; reserved RAM addresses
|
||||||
; 00-0f - free use (Z0-Z15)
|
; 00-0f - free
|
||||||
; 10-1f - arguments / return values (ARG0-ARG15)
|
; 10-1f - arguments / return values
|
||||||
; 20-ff - free
|
; 20-ff - free
|
||||||
; 0100 - 01FF Stack
|
; 0100 - 01FF Stack
|
||||||
; 0200,0201 keybuffer write/read pointer
|
; 0200,0201 keybuffer write/read pointer
|
||||||
; 0202-02ff keybuffer
|
; 0202-02ff keybuffer
|
||||||
; 0300 lcd character counter
|
; 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 "io_W65C22.h65"
|
||||||
.include "utility.h65"
|
.include "utility.h65"
|
||||||
.importzp Z0,Z1,Z2,Z3,Z4,Z5,Z6,Z7,Z8,Z9,Z10,Z11,Z12,Z13,Z14,Z15
|
|
||||||
.importzp ARG0,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8,ARG9,ARG10,ARG11,ARG12,ARG13,ARG14,ARG15
|
|
||||||
|
|
||||||
; Z0 = $0
|
; ARGUMENTS
|
||||||
; Z1 = $1
|
; a,x,y can also be used
|
||||||
; Z2 = $2
|
ARG0 = $10
|
||||||
; Z3 = $3
|
ARG1 = $11
|
||||||
; Z4 = $4
|
ARG2 = $12
|
||||||
; Z5 = $5
|
ARG3 = $13
|
||||||
; Z6 = $6
|
ARG4 = $14
|
||||||
; Z7 = $7
|
ARG5 = $15
|
||||||
; Z8 = $8
|
ARG6 = $16
|
||||||
; Z9 = $9
|
ARG7 = $17
|
||||||
; Z10 = $a
|
ARG8 = $18
|
||||||
; Z11 = $b
|
ARG9 = $19
|
||||||
; Z12 = $c
|
ARG10 = $1a
|
||||||
; Z13 = $d
|
ARG11 = $1b
|
||||||
; Z14 = $e
|
ARG12 = $1c
|
||||||
; Z15 = $f
|
ARG13 = $1d
|
||||||
; ; ARGUMENTS
|
ARG14 = $1e
|
||||||
; ; a,x,y can also be used
|
ARG15 = $1f
|
||||||
; ARG0 = $10
|
|
||||||
; ARG1 = $11
|
|
||||||
; ARG2 = $12
|
|
||||||
; ARG3 = $13
|
|
||||||
; ARG4 = $14
|
|
||||||
; ARG5 = $15
|
|
||||||
; ARG6 = $16
|
|
||||||
; ARG7 = $17
|
|
||||||
; ARG8 = $18
|
|
||||||
; ARG9 = $19
|
|
||||||
; ARG10 = $1a
|
|
||||||
; ARG11 = $1b
|
|
||||||
; ARG12 = $1c
|
|
||||||
; ARG13 = $1d
|
|
||||||
; ARG14 = $1e
|
|
||||||
; ARG15 = $1f
|
|
||||||
|
|
||||||
|
|
||||||
; RETURN VALUE
|
; RETURN VALUE
|
||||||
|
; in a
|
||||||
|
|
||||||
.segment "VIA1"
|
.segment "VIA1"
|
||||||
; IO1: .res 16
|
; IO1: .res 16
|
||||||
IO1 = $6000
|
IO1 = $6000
|
||||||
|
@ -1,42 +1,3 @@
|
|||||||
; .include "system.h65"
|
|
||||||
.exportzp Z0,Z1,Z2,Z3,Z4,Z5,Z6,Z7,Z8,Z9,Z10,Z11,Z12,Z13,Z14,Z15
|
|
||||||
.exportzp ARG0,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8,ARG9,ARG10,ARG11,ARG12,ARG13,ARG14,ARG15
|
|
||||||
|
|
||||||
.zeropage
|
.zeropage
|
||||||
.org $0
|
.org $10
|
||||||
.assert * = $0, error, "Code not at 0"
|
.res 16
|
||||||
Z0: .res 1
|
|
||||||
Z1: .res 1
|
|
||||||
Z2: .res 1
|
|
||||||
Z3: .res 1
|
|
||||||
Z4: .res 1
|
|
||||||
Z5: .res 1
|
|
||||||
Z6: .res 1
|
|
||||||
Z7: .res 1
|
|
||||||
Z8: .res 1
|
|
||||||
Z9: .res 1
|
|
||||||
Z10: .res 1
|
|
||||||
Z11: .res 1
|
|
||||||
Z12: .res 1
|
|
||||||
Z13: .res 1
|
|
||||||
Z14: .res 1
|
|
||||||
Z15: .res 1
|
|
||||||
; ARGUMENTS
|
|
||||||
; a,x,y can also be used
|
|
||||||
.assert * = $10, error, "Code not at 10"
|
|
||||||
ARG0: .res 1
|
|
||||||
ARG1: .res 1
|
|
||||||
ARG2: .res 1
|
|
||||||
ARG3: .res 1
|
|
||||||
ARG4: .res 1
|
|
||||||
ARG5: .res 1
|
|
||||||
ARG6: .res 1
|
|
||||||
ARG7: .res 1
|
|
||||||
ARG8: .res 1
|
|
||||||
ARG9: .res 1
|
|
||||||
ARG10: .res 1
|
|
||||||
ARG11: .res 1
|
|
||||||
ARG12: .res 1
|
|
||||||
ARG13: .res 1
|
|
||||||
ARG14: .res 1
|
|
||||||
ARG15: .res 1
|
|
||||||
|
61
test.s65
61
test.s65
@ -1,8 +1,55 @@
|
|||||||
.include "system/system.h65"
|
;.include "system/system.h65"
|
||||||
|
;.segment "CODE"
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; 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
|
||||||
|
|
||||||
|
;@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
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; reset vector
|
||||||
|
;;********************************************************************************
|
||||||
|
;.segment "RESET_VECTOR"
|
||||||
|
; .word nmi
|
||||||
|
; .word reset
|
||||||
|
; .word irq
|
||||||
|
|
||||||
.segment "TEST"
|
|
||||||
label:
|
|
||||||
JsrIndirect $2022
|
|
||||||
.byte 0,1,2,3,4
|
|
||||||
JsrIndirect {($2022,x)}, label
|
|
||||||
.byte 5,6,7,8,9
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
.include "string.h65"
|
.include "string.h65"
|
||||||
.include "math.h65"
|
.include "math.h65"
|
||||||
Export str,hex_char_to_uint8, hex_str_to_uint, uint8_to_hex_str, uint_to_hex_str
|
Export str,hex_char_to_uint8, hex_str_to_uint, uint8_to_hex_str
|
||||||
|
|
||||||
.code
|
.code
|
||||||
;
|
;
|
||||||
@ -130,55 +130,6 @@ Export str,hex_char_to_uint8, hex_str_to_uint, uint8_to_hex_str, uint_to_hex_str
|
|||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
;;********************************************************************************
|
|
||||||
;; @function Convert a 1 byte number into two hex characters
|
|
||||||
;; @param A: Size of the number in bytes
|
|
||||||
;; @param X: Offset onto ARG4, so that the number starts at `ARG4+x` (BE)
|
|
||||||
;; @param ARG2-3: Pointer to output string
|
|
||||||
;; @param Y: Offset onto the string in ARG2-3
|
|
||||||
;; @returns A: 0
|
|
||||||
;; @returns X: Offset onto ARG4, past the end of the number
|
|
||||||
;; @returns Y: Offset onto the the string in ARG2-3, past the end of the number
|
|
||||||
;; @returns N: Clear if success, else set
|
|
||||||
;; @modifies A,X,Y
|
|
||||||
;;********************************************************************************
|
|
||||||
.proc uint_to_hex_str
|
|
||||||
@loop:
|
|
||||||
cmp #0
|
|
||||||
beq @rts
|
|
||||||
pha
|
|
||||||
lda ARG4,x
|
|
||||||
phx
|
|
||||||
pha
|
|
||||||
and #%00001111
|
|
||||||
tax
|
|
||||||
lda HEX_CHARS_UPPER,x
|
|
||||||
sta (ARG2),y
|
|
||||||
pla
|
|
||||||
iny
|
|
||||||
beq @overflow2
|
|
||||||
div A,16
|
|
||||||
and #%00001111
|
|
||||||
tax
|
|
||||||
lda HEX_CHARS_UPPER,x
|
|
||||||
sta (ARG2),y
|
|
||||||
iny
|
|
||||||
beq @overflow2
|
|
||||||
plx
|
|
||||||
pla
|
|
||||||
inx
|
|
||||||
beq @overflow
|
|
||||||
bra @loop
|
|
||||||
@overflow2:
|
|
||||||
plx
|
|
||||||
pla
|
|
||||||
@overflow:
|
|
||||||
lda #$ff ; set n
|
|
||||||
@rts:
|
|
||||||
rts
|
|
||||||
.endproc
|
|
||||||
|
|
||||||
|
|
||||||
.rodata
|
.rodata
|
||||||
HEX_CHARS_UPPER: .byte "0123456789ABCDEF"
|
HEX_CHARS_UPPER: .byte "0123456789ABCDEF"
|
||||||
HEX_CHARS_LOWER: .byte "0123456789abcdef"
|
HEX_CHARS_LOWER: .byte "0123456789abcdef"
|
||||||
|
@ -12,8 +12,7 @@ INCLUDE_STRING = 1
|
|||||||
|
|
||||||
.scope str
|
.scope str
|
||||||
Import str, strf
|
Import str, strf
|
||||||
Import str, hex_char_to_uint8, hex_str_to_uint
|
Import str, hex_char_to_uint8, hex_str_to_uint, uint8_to_hex_str
|
||||||
Import str, uint8_to_hex_str, uint_to_hex_str
|
|
||||||
|
|
||||||
|
|
||||||
.macro _StrfStoreArg arg
|
.macro _StrfStoreArg arg
|
||||||
@ -36,7 +35,7 @@ Import str, uint8_to_hex_str, uint_to_hex_str
|
|||||||
;; @param out: Output string address
|
;; @param out: Output string address
|
||||||
;; @param x0-x9: Additional parameters
|
;; @param x0-x9: Additional parameters
|
||||||
;; @warning Addresses as additional paramters must be passed like this `#<addr,#>addr`
|
;; @warning Addresses as additional paramters must be passed like this `#<addr,#>addr`
|
||||||
;; @modifies: A, X, Y, ARG4, ARG5
|
;; @modifies: A, X, Y
|
||||||
;; @see strf
|
;; @see strf
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
.macro Strf fmt,out,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9
|
.macro Strf fmt,out,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9
|
||||||
@ -74,5 +73,8 @@ Import str, uint8_to_hex_str, uint_to_hex_str
|
|||||||
; .out .sprintf("info: Strf: called with %d arguments", @N_ARGS)
|
; .out .sprintf("info: Strf: called with %d arguments", @N_ARGS)
|
||||||
.endmacro
|
.endmacro
|
||||||
|
|
||||||
|
; TODO allocate zp memory
|
||||||
|
fmt_idx = $30
|
||||||
|
out_idx = $31
|
||||||
.endscope
|
.endscope
|
||||||
.endif ; guard
|
.endif ; guard
|
||||||
|
@ -1,12 +1,6 @@
|
|||||||
.include "string.h65"
|
.include "string.h65"
|
||||||
Export str, strf
|
Export str, strf
|
||||||
|
|
||||||
.zeropage
|
|
||||||
fmt_idx: .res 1
|
|
||||||
out_idx: .res 1
|
|
||||||
pad_zero:.res 1
|
|
||||||
digits: .res 1
|
|
||||||
; addr: .res 2
|
|
||||||
.code
|
.code
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
;; @function Format a string
|
;; @function Format a string
|
||||||
@ -17,14 +11,14 @@ digits: .res 1
|
|||||||
;; - X: unsigned hex integer (2 byte) -> 4 chars TODO
|
;; - X: unsigned hex integer (2 byte) -> 4 chars TODO
|
||||||
;; - u: unsigned decimal integer (1 byte) TODO
|
;; - u: unsigned decimal integer (1 byte) TODO
|
||||||
;; - U: unsigned decimal integer (2 bytes) TODO
|
;; - U: unsigned decimal integer (2 bytes) TODO
|
||||||
;; - s: null-terminated string (2 bytes ptr)
|
|
||||||
;; - c: char
|
|
||||||
;; @param ARG0-1: Format string address
|
;; @param ARG0-1: Format string address
|
||||||
;; @param ARG2-3: Output string address
|
;; @param ARG2-3: Output string address
|
||||||
;; @param ARG4+: Additional parameters
|
;; @param ARG4+: Additional parameters
|
||||||
;; @returns
|
;; @returns
|
||||||
;; @modifies: A, X, Y, ARG4, ARG5
|
;; @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
|
||||||
@ -33,7 +27,7 @@ digits: .res 1
|
|||||||
@loop:
|
@loop:
|
||||||
ldy fmt_idx
|
ldy fmt_idx
|
||||||
lda (ARG0),y
|
lda (ARG0),y
|
||||||
jeq @null
|
beq @null
|
||||||
cmp #'%'
|
cmp #'%'
|
||||||
beq @percent
|
beq @percent
|
||||||
@normal_char: ; store A in output string
|
@normal_char: ; store A in output string
|
||||||
@ -48,88 +42,29 @@ digits: .res 1
|
|||||||
sty fmt_idx
|
sty fmt_idx
|
||||||
lda (ARG0),y
|
lda (ARG0),y
|
||||||
beq @null
|
beq @null
|
||||||
; padding
|
|
||||||
cmp #'0'
|
|
||||||
beq @percent_zero
|
|
||||||
stz pad_zero
|
|
||||||
; formats
|
; formats
|
||||||
cmp #'x'
|
cmp #'x'
|
||||||
beq @format_hex1
|
beq @format_hex1
|
||||||
cmp #'X'
|
|
||||||
beq @format_hex2
|
|
||||||
cmp #'c'
|
|
||||||
beq @format_char
|
|
||||||
|
|
||||||
bra @normal_char
|
bra @normal_char
|
||||||
@percent_zero:
|
|
||||||
sta pad_zero
|
|
||||||
bra @percent
|
|
||||||
; @percent_num:
|
|
||||||
; sta pad_zero
|
|
||||||
; bra @percent
|
|
||||||
|
|
||||||
@format_hex1: ; 1 byte hex -> 2 chars
|
@format_hex1: ; 1 byte hex -> 2 chars
|
||||||
lda ARG4,x
|
lda ARG4,x
|
||||||
phx
|
phx
|
||||||
jsr str::uint8_to_hex_str
|
jsr str::uint8_to_hex_str
|
||||||
ldy out_idx
|
ldy out_idx
|
||||||
sta (ARG2),y ; most sig digit
|
sta (ARG2),y ; most sig digit
|
||||||
txa
|
|
||||||
plx
|
|
||||||
iny
|
iny
|
||||||
beq @out_overflow
|
beq @out_overflow
|
||||||
|
txa
|
||||||
sta (ARG2),y ; least sig digit
|
sta (ARG2),y ; least sig digit
|
||||||
iny
|
iny
|
||||||
beq @out_overflow
|
beq @out_overflow
|
||||||
sty out_idx
|
sty out_idx
|
||||||
|
plx
|
||||||
inx ; 1 byte of args handeled
|
inx ; 1 byte of args handeled
|
||||||
bra @format_return
|
; bra @format_return
|
||||||
|
@format_return: ; increment fmt_idx to swallow the formating char
|
||||||
@format_hex2: ; 2 byte hex -> 4 chars
|
inc fmt_idx
|
||||||
lda #2
|
bra @loop
|
||||||
ldy out_idx
|
|
||||||
jsr str::uint_to_hex_str
|
|
||||||
bmi @out_overflow ; might also be x overflow
|
|
||||||
sty out_idx
|
|
||||||
bra @format_return
|
|
||||||
|
|
||||||
@format_char: ; 1 char
|
|
||||||
lda ARG4,x
|
|
||||||
ldy out_idx
|
|
||||||
sta (ARG2),y
|
|
||||||
inc out_idx
|
|
||||||
beq @out_overflow
|
|
||||||
inx
|
|
||||||
bra @format_return
|
|
||||||
|
|
||||||
@format_string: ; string
|
|
||||||
ldy #0
|
|
||||||
cpx #0
|
|
||||||
beq @format_string_loop
|
|
||||||
; store the pointer to the string at arg4-5
|
|
||||||
@format_string_move_ptr:
|
|
||||||
lda ARG4,x
|
|
||||||
sta ARG4
|
|
||||||
lda ARG5,x
|
|
||||||
sta ARG5
|
|
||||||
@format_string_loop:
|
|
||||||
lda (ARG4),y
|
|
||||||
beq @format_string_end ; if null
|
|
||||||
phy
|
|
||||||
ldy out_idx
|
|
||||||
sta (ARG2),y
|
|
||||||
inc out_idx
|
|
||||||
beq @out_overflow
|
|
||||||
ply
|
|
||||||
iny
|
|
||||||
@format_string_end:
|
|
||||||
inx
|
|
||||||
inx
|
|
||||||
bra @format_return
|
|
||||||
|
|
||||||
@format_return: ; increment fmt_idx to account for the formating char
|
|
||||||
inc fmt_idx ; at this point, out_idx will always overflow first
|
|
||||||
jmp @loop
|
|
||||||
@out_overflow: ; store 0 in last position
|
@out_overflow: ; store 0 in last position
|
||||||
ldy #$ff
|
ldy #$ff
|
||||||
sty out_idx
|
sty out_idx
|
||||||
|
56
utility.h65
56
utility.h65
@ -8,57 +8,25 @@ INCLUDE_UTILITY = 1
|
|||||||
.feature underline_in_numbers
|
.feature underline_in_numbers
|
||||||
|
|
||||||
|
|
||||||
;;********************************************************************************
|
;********************************************************************************
|
||||||
;; @macro Update a byte in memory using a mask
|
; @macro Update a byte in memory using a mask
|
||||||
;; @param addr Address of the byte to update
|
; @param addr Address of the byte to update
|
||||||
;; @param value New value
|
; @param value New value
|
||||||
;; @param mask Mask of the bits to affect by the new value
|
; @param mask Mask of the bits to affect by the new value
|
||||||
;; @details
|
; @details
|
||||||
;; xor #value with addr -> only bits that need to flip are 1
|
; xor #value with addr -> only bits that need to flip are 1
|
||||||
;; and result with #mask -> only selected bits that need to flip stay 1
|
; and result with #mask -> only selected bits that need to flip stay 1
|
||||||
;; xor result with addr -> flips selected bits
|
; xor result with addr -> flips selected bits
|
||||||
;;********************************************************************************
|
;********************************************************************************
|
||||||
.macro MaskedWrite addr,value,mask
|
.macro MaskedWrite addr,value,mask
|
||||||
lda value
|
lda #value
|
||||||
eor addr
|
eor addr
|
||||||
and mask
|
and #mask
|
||||||
eor addr
|
eor addr
|
||||||
sta addr
|
sta addr
|
||||||
.endmacro
|
.endmacro
|
||||||
|
|
||||||
|
|
||||||
;;********************************************************************************
|
|
||||||
;; @macro Jump to the subroutine and let the routine return at another location
|
|
||||||
;; @details
|
|
||||||
;; By using a indirect address `(addr)` and no ret_val, this macro behaves
|
|
||||||
;; like an indirect version of jsr.
|
|
||||||
;; @param addr Target of the jump (can be: `addr`, `(addr)` or `{(addr,x)}`
|
|
||||||
;; @param ret_addr Return address (optional)
|
|
||||||
;; @details
|
|
||||||
;;********************************************************************************
|
|
||||||
.macro JsrIndirect addr,ret_addr
|
|
||||||
; -1 because rts increments it
|
|
||||||
.if .blank(ret_addr)
|
|
||||||
lda #<(:+ - 1)
|
|
||||||
pha
|
|
||||||
lda #>(:+ - 1)
|
|
||||||
pha
|
|
||||||
.else
|
|
||||||
lda #<(ret_addr -1)
|
|
||||||
pha
|
|
||||||
lda #>(ret_addr -1)
|
|
||||||
pha
|
|
||||||
.endif
|
|
||||||
jmp addr
|
|
||||||
.if .blank(ret_addr)
|
|
||||||
:
|
|
||||||
.endif
|
|
||||||
.endmacro
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_n_genlabel .set 0
|
_n_genlabel .set 0
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
;; @macro Generate a unique label
|
;; @macro Generate a unique label
|
||||||
|
Loading…
Reference in New Issue
Block a user