wip
This commit is contained in:
parent
27a901c7c0
commit
3d773390bf
22
main.s65
22
main.s65
@ -65,7 +65,7 @@ irq:
|
||||
@irq_io1:
|
||||
lda IO1 + IO::IFR
|
||||
sta irq_via_ifr
|
||||
bbr7 irq_via_ifr,@irq_io2 ; skip
|
||||
bbr7 irq_via_ifr,@irq_io1 ; skip
|
||||
bbs2 irq_via_ifr,@irq_kb1 ; shit reg -> first 8 bits
|
||||
bbs5 irq_via_ifr,@irq_kb2 ; timer -> last 3 bits
|
||||
@irq_io2:
|
||||
@ -74,6 +74,7 @@ irq:
|
||||
bbr7 irq_via_ifr,@irq_return ; skip
|
||||
bbs2 irq_via_ifr,@irq_spi_p ; check SR
|
||||
bbs1 irq_via_ifr,@irq_keypad ; check CA1
|
||||
|
||||
; this SHOULD never be reached
|
||||
jsr lcd::clear
|
||||
Print "Unknown IRQ"
|
||||
@ -81,23 +82,18 @@ irq:
|
||||
lda #$ff
|
||||
sta IO1 + IO::IFR
|
||||
sta IO2 + IO::IFR
|
||||
rti
|
||||
; bra @irq_return
|
||||
@irq_keypad:
|
||||
lda #<@irq_return
|
||||
pha
|
||||
lda #>@irq_return
|
||||
pha
|
||||
jmp (spi_p::irq_handler)
|
||||
@irq_spi_p:
|
||||
jsr spi_p::read
|
||||
bra @irq_return
|
||||
@irq_keypad:
|
||||
jsr kp::read_irq
|
||||
bra @irq_return
|
||||
@irq_spi_p:
|
||||
JsrIndirect (spi_p::irq_handler), @irq_return
|
||||
@irq_kb1:
|
||||
; PrintNC "<30>"
|
||||
Print "$3000"
|
||||
jsr $3000
|
||||
bra @irq_return
|
||||
@irq_kb2:
|
||||
; PrintNC "<31>"
|
||||
Print "$3100"
|
||||
jsr $3100
|
||||
bra @irq_return
|
||||
; @irq_dht:
|
||||
|
@ -4,43 +4,56 @@
|
||||
.include "lcd.h65"
|
||||
.include "chars.h65"
|
||||
.import home:absolute
|
||||
.import SPI_IO
|
||||
.import CODE_START: absolute
|
||||
.import __SPI_SIZE__
|
||||
|
||||
.export spi_menu
|
||||
.bss
|
||||
trans_bytes: .res 1
|
||||
trans_pages: .res 1
|
||||
status: .res 1
|
||||
trans_bytes: .res 2 ; used to check if screen needs to be updated
|
||||
status_char: .res 1
|
||||
status_str: .res 17 ; 16 + null
|
||||
|
||||
.code
|
||||
.proc spi_menu
|
||||
stz trans_bytes
|
||||
stz trans_pages
|
||||
lda #'X'
|
||||
sta status
|
||||
stz trans_bytes+1
|
||||
@print_menu:
|
||||
jsr lcd::clear
|
||||
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:
|
||||
lda #lcd::LINE4
|
||||
jsr lcd::set_position
|
||||
Strf FMT_STATUS,status_str,trans_pages,trans_bytes,status
|
||||
Strf "%x%xb Status: %c",status_str,trans_bytes+1,trans_bytes,status_char
|
||||
PrintNC status_str
|
||||
@loop:
|
||||
; check if a byte has been transferred
|
||||
@check_byte:
|
||||
lda spi_p::bytes_written
|
||||
@check_received:
|
||||
lda spi_p::recv_bytes
|
||||
cmp trans_bytes
|
||||
beq @read_keypad
|
||||
@byte_written:
|
||||
@byte_received:
|
||||
sta trans_bytes
|
||||
@check_page:
|
||||
lda spi_p::pages_written
|
||||
cmp trans_pages
|
||||
beq @read_keypad
|
||||
@page_written:
|
||||
sta trans_pages
|
||||
lda spi_p::recv_bytes+1
|
||||
lda trans_bytes+1
|
||||
bra @print_status
|
||||
@read_keypad:
|
||||
lda kp::_DEBUG_VAL
|
||||
@ -57,22 +70,26 @@ status_str: .res 17 ; 16 + null
|
||||
beq @spi_end
|
||||
cmp #'C'
|
||||
beq @spi_jump
|
||||
bra @loop
|
||||
bra @update_status ; any other key
|
||||
@spi_begin:
|
||||
lda #'@'
|
||||
sta status
|
||||
jsr spi_p::begin
|
||||
lda #<CODE_START
|
||||
sta ARG0
|
||||
lda #>CODE_START
|
||||
sta ARG1
|
||||
lda #<__SPI_SIZE__
|
||||
sta ARG2
|
||||
lda #>__SPI_SIZE__
|
||||
sta ARG3
|
||||
jsr spi_p::begin_read
|
||||
jmp @print_menu
|
||||
@spi_end:
|
||||
lda #'X'
|
||||
sta status
|
||||
jsr spi_p::end
|
||||
jmp @print_menu
|
||||
@spi_jump:
|
||||
jsr spi_p::end
|
||||
jsr lcd::clear
|
||||
Print START
|
||||
jmp spi_p::CODE_START
|
||||
jmp CODE_START
|
||||
@return_home:
|
||||
jsr spi_p::end
|
||||
jmp home
|
||||
|
26
spicode.s65
26
spicode.s65
@ -3,6 +3,7 @@
|
||||
.include "lcd.h65"
|
||||
.include "math.h65"
|
||||
.include "keypad.h65"
|
||||
.include "keyboard.h65"
|
||||
.include "chars.h65"
|
||||
.import homeloop:absolute
|
||||
.import home:absolute
|
||||
@ -12,9 +13,6 @@
|
||||
|
||||
.import memcopy
|
||||
|
||||
.scope kb
|
||||
KB_IO = IO1
|
||||
.endscope
|
||||
|
||||
|
||||
CODE_START:
|
||||
@ -60,7 +58,7 @@ CODE_START:
|
||||
|
||||
; PrintNC $3000
|
||||
|
||||
jsr kbinit
|
||||
jsr kb::init
|
||||
|
||||
lda #'%'
|
||||
jsr lcd::print_char
|
||||
@ -110,7 +108,7 @@ CODE_START:
|
||||
jsr lcd::print_char
|
||||
bra @loop
|
||||
@lB:
|
||||
Strf fmt_str, out_str, keycode
|
||||
Strf fmt_str, out_str, kb::keycode
|
||||
Print out_str
|
||||
bra @loop
|
||||
@lC:
|
||||
@ -168,11 +166,11 @@ CODE_START:
|
||||
; .endproc
|
||||
|
||||
|
||||
.proc irq_on_timer
|
||||
.proc irq_timer_handler
|
||||
; lda #'<'
|
||||
; jsr lcd::print_char
|
||||
lda kb::KB_IO + IO::SR
|
||||
sta key_read + 1
|
||||
sta kb::key_read + 1
|
||||
|
||||
lda kb::KB_IO + IO::T2CL ; clear interrupt flag
|
||||
|
||||
@ -190,16 +188,16 @@ CODE_START:
|
||||
ror
|
||||
ror
|
||||
ror
|
||||
lda key_read ; not affecting carry
|
||||
lda kb::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
|
||||
sta kb::keycode
|
||||
|
||||
Strf fmt_str2, out_str, keycode, key_read, key_read+1
|
||||
Strf fmt_str2, out_str, kb::keycode, kb::key_read, kb::key_read+1
|
||||
PrintNC out_str
|
||||
|
||||
stz key_read
|
||||
stz key_read+1
|
||||
stz kb::key_read
|
||||
stz kb::key_read+1
|
||||
|
||||
rts
|
||||
.endproc
|
||||
@ -209,7 +207,7 @@ CODE_START:
|
||||
kb_irq1:
|
||||
; lda #'!'
|
||||
; jsr lcd::print_char
|
||||
jsr kb::on_shift_reg_irq
|
||||
jsr kb::irq_shift_reg_handler
|
||||
; lda #':'
|
||||
; jsr lcd::print_char
|
||||
rts
|
||||
@ -218,7 +216,7 @@ kb_irq2:
|
||||
; lda #'?'
|
||||
; jsr lcd::print_char
|
||||
; jsr kb::on_timer_irq
|
||||
jsr irq_on_timer
|
||||
jsr irq_timer_handler
|
||||
; lda #';'
|
||||
; jsr lcd::print_char
|
||||
rts
|
||||
|
@ -1,7 +1,7 @@
|
||||
;********************************************************************************
|
||||
; @module irq_handler
|
||||
; @type system
|
||||
;********************************************************************************
|
||||
;;********************************************************************************
|
||||
;; @module irq_handler
|
||||
;; @type system
|
||||
;;********************************************************************************
|
||||
.ifndef INCLUDE_IRQ_HANDLER
|
||||
INCLUDE_IRQ_HANDLER = 1
|
||||
|
||||
|
@ -22,7 +22,7 @@ charcount: .res 1
|
||||
lda #$ff ; RB 0-7 output
|
||||
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
|
||||
; sta lcd::LCD_IO+IO::DDRA
|
||||
|
||||
|
@ -12,7 +12,9 @@ INCLUDE_SPI = 1
|
||||
|
||||
.scope spi_p
|
||||
SPI_IO = IO2
|
||||
Import spi_p, begin_read, irq_read_byte, begin_write, irq_write_byte, end, recv_bytes, sent_bytes, status
|
||||
Import spi_p, irq_handler, end, status
|
||||
Import spi_p, begin_read, irq_read_byte, recv_bytes
|
||||
Import spi_p, begin_write, irq_write_byte, sent_bytes
|
||||
|
||||
.enum STATUS
|
||||
XFER_SIZEL = %10000000
|
||||
@ -24,3 +26,17 @@ Import spi_p, begin_read, irq_read_byte, begin_write, irq_write_byte, end, recv_
|
||||
|
||||
.endscope
|
||||
.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,6 +1,9 @@
|
||||
.include "spi.h65"
|
||||
.include "system.h65"
|
||||
|
||||
Export spi_p, begin_read, irq_read_byte, begin_write, irq_write_byte, end, recv_bytes, sent_bytes, status, spi_irq
|
||||
Export spi_p, irq_handler, end, status
|
||||
Export spi_p, begin_read, irq_read_byte, recv_bytes
|
||||
Export spi_p, begin_write, irq_write_byte, sent_bytes
|
||||
|
||||
.zeropage
|
||||
buffer_start: .res 2
|
||||
@ -17,19 +20,14 @@ SPI_IO := spi_p::SPI_IO
|
||||
; spi-transferred code will be placed here
|
||||
; SPI_P = as peripheral
|
||||
.code
|
||||
; .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
|
||||
|
||||
;;********************************************************************************
|
||||
;; @function Begin listening for SPI transfers
|
||||
;;********************************************************************************
|
||||
.proc init
|
||||
lda #spi_p::STATUS::DONE
|
||||
sta status
|
||||
.endproc
|
||||
|
||||
|
||||
;;********************************************************************************
|
||||
@ -48,7 +46,7 @@ SPI_IO := spi_p::SPI_IO
|
||||
.proc begin_read
|
||||
stz recv_bytes
|
||||
stz recv_bytes+1
|
||||
lda #%spi_p::STATUS::XFER_SIZEL
|
||||
lda #spi_p::STATUS::XFER_SIZEL
|
||||
sta status
|
||||
|
||||
; store address in zp
|
||||
@ -186,7 +184,7 @@ SPI_IO := spi_p::SPI_IO
|
||||
; write the first byte
|
||||
@write_size1:
|
||||
lda buffer_size
|
||||
sta SPI_IO+IO_SR
|
||||
sta SPI_IO+IO::SR
|
||||
lda #spi_p::STATUS::XFER_SIZEH
|
||||
sta status
|
||||
rts
|
||||
@ -236,11 +234,9 @@ SPI_IO := spi_p::SPI_IO
|
||||
rts
|
||||
@write_size2:
|
||||
lda buffer_size+1
|
||||
sta SPI_IO+IO_SR
|
||||
sta SPI_IO+IO::SR
|
||||
lda #spi_p::STATUS::XFER
|
||||
sta status
|
||||
rts
|
||||
.endproc
|
||||
|
||||
|
||||
.endproc
|
||||
|
@ -1,6 +1,6 @@
|
||||
.include "string.h65"
|
||||
.include "math.h65"
|
||||
Export str,hex_char_to_uint8, hex_str_to_uint, uint8_to_hex_str
|
||||
Export str,hex_char_to_uint8, hex_str_to_uint, uint8_to_hex_str, uint_to_hex_str
|
||||
|
||||
.code
|
||||
;
|
||||
@ -130,6 +130,55 @@ Export str,hex_char_to_uint8, hex_str_to_uint, uint8_to_hex_str
|
||||
.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
|
||||
HEX_CHARS_UPPER: .byte "0123456789ABCDEF"
|
||||
HEX_CHARS_LOWER: .byte "0123456789abcdef"
|
||||
|
@ -12,7 +12,8 @@ INCLUDE_STRING = 1
|
||||
|
||||
.scope str
|
||||
Import str, strf
|
||||
Import str, hex_char_to_uint8, hex_str_to_uint, uint8_to_hex_str
|
||||
Import str, hex_char_to_uint8, hex_str_to_uint
|
||||
Import str, uint8_to_hex_str, uint_to_hex_str
|
||||
|
||||
|
||||
.macro _StrfStoreArg arg
|
||||
@ -35,7 +36,7 @@ Import str, hex_char_to_uint8, hex_str_to_uint, uint8_to_hex_str
|
||||
;; @param out: Output string address
|
||||
;; @param x0-x9: Additional parameters
|
||||
;; @warning Addresses as additional paramters must be passed like this `#<addr,#>addr`
|
||||
;; @modifies: A, X, Y
|
||||
;; @modifies: A, X, Y, ARG4, ARG5
|
||||
;; @see strf
|
||||
;;********************************************************************************
|
||||
.macro Strf fmt,out,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9
|
||||
@ -73,8 +74,5 @@ Import str, hex_char_to_uint8, hex_str_to_uint, uint8_to_hex_str
|
||||
; .out .sprintf("info: Strf: called with %d arguments", @N_ARGS)
|
||||
.endmacro
|
||||
|
||||
; TODO allocate zp memory
|
||||
fmt_idx = $30
|
||||
out_idx = $31
|
||||
.endscope
|
||||
.endif ; guard
|
||||
|
103
util/string.s65
103
util/string.s65
@ -1,24 +1,30 @@
|
||||
.include "string.h65"
|
||||
Export str, strf
|
||||
|
||||
.zeropage
|
||||
fmt_idx: .res 1
|
||||
out_idx: .res 1
|
||||
pad_zero:.res 1
|
||||
digits: .res 1
|
||||
; addr: .res 2
|
||||
.code
|
||||
;;********************************************************************************
|
||||
;; @function Format a string
|
||||
;; @details
|
||||
;; If there is no value to be read, the Pz will be set
|
||||
;; Formats:
|
||||
;; - x: unsigned hex integer (1 byte) -> 2 chars
|
||||
;; - X: unsigned hex integer (2 byte) -> 4 chars TODO
|
||||
;; - u: unsigned decimal integer (1 byte) TODO
|
||||
;; - U: unsigned decimal integer (2 bytes) TODO
|
||||
;; If there is no value to be read, the Pz will be set
|
||||
;; Formats:
|
||||
;; - x: unsigned hex integer (1 byte) -> 2 chars
|
||||
;; - X: unsigned hex integer (2 byte) -> 4 chars TODO
|
||||
;; - u: unsigned decimal integer (1 byte) TODO
|
||||
;; - U: unsigned decimal integer (2 bytes) TODO
|
||||
;; - s: null-terminated string (2 bytes ptr)
|
||||
;; - c: char
|
||||
;; @param ARG0-1: Format string address
|
||||
;; @param ARG2-3: Output string address
|
||||
;; @param ARG4+: Additional parameters
|
||||
;; @returns
|
||||
;; @modifies: A, X, Y
|
||||
;; @modifies: A, X, Y, ARG4, ARG5
|
||||
;;********************************************************************************
|
||||
out_idx := str::out_idx
|
||||
fmt_idx := str::fmt_idx
|
||||
.proc strf
|
||||
stz out_idx
|
||||
stz fmt_idx
|
||||
@ -27,7 +33,7 @@ fmt_idx := str::fmt_idx
|
||||
@loop:
|
||||
ldy fmt_idx
|
||||
lda (ARG0),y
|
||||
beq @null
|
||||
jeq @null
|
||||
cmp #'%'
|
||||
beq @percent
|
||||
@normal_char: ; store A in output string
|
||||
@ -42,29 +48,88 @@ fmt_idx := str::fmt_idx
|
||||
sty fmt_idx
|
||||
lda (ARG0),y
|
||||
beq @null
|
||||
; padding
|
||||
cmp #'0'
|
||||
beq @percent_zero
|
||||
stz pad_zero
|
||||
; formats
|
||||
cmp #'x'
|
||||
beq @format_hex1
|
||||
cmp #'X'
|
||||
beq @format_hex2
|
||||
cmp #'c'
|
||||
beq @format_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
|
||||
lda ARG4,x
|
||||
phx
|
||||
jsr str::uint8_to_hex_str
|
||||
ldy out_idx
|
||||
sta (ARG2),y ; most sig digit
|
||||
jsr str::uint8_to_hex_str
|
||||
ldy out_idx
|
||||
sta (ARG2),y ; most sig digit
|
||||
txa
|
||||
plx
|
||||
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
|
||||
bra @format_return
|
||||
|
||||
@format_hex2: ; 2 byte hex -> 4 chars
|
||||
lda #2
|
||||
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
|
||||
ldy #$ff
|
||||
sty out_idx
|
||||
|
56
utility.h65
56
utility.h65
@ -8,25 +8,57 @@ INCLUDE_UTILITY = 1
|
||||
.feature underline_in_numbers
|
||||
|
||||
|
||||
;********************************************************************************
|
||||
; @macro Update a byte in memory using a mask
|
||||
; @param addr Address of the byte to update
|
||||
; @param value New value
|
||||
; @param mask Mask of the bits to affect by the new value
|
||||
; @details
|
||||
; 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
|
||||
; xor result with addr -> flips selected bits
|
||||
;********************************************************************************
|
||||
;;********************************************************************************
|
||||
;; @macro Update a byte in memory using a mask
|
||||
;; @param addr Address of the byte to update
|
||||
;; @param value New value
|
||||
;; @param mask Mask of the bits to affect by the new value
|
||||
;; @details
|
||||
;; 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
|
||||
;; xor result with addr -> flips selected bits
|
||||
;;********************************************************************************
|
||||
.macro MaskedWrite addr,value,mask
|
||||
lda #value
|
||||
lda value
|
||||
eor addr
|
||||
and #mask
|
||||
and mask
|
||||
eor addr
|
||||
sta addr
|
||||
.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
|
||||
;;********************************************************************************
|
||||
;; @macro Generate a unique label
|
||||
|
Loading…
Reference in New Issue
Block a user