mirror of
https://github.com/stid/woz64.git
synced 2025-01-17 15:30:40 +00:00
feat: optimizations
This commit is contained in:
parent
b4ed402b31
commit
6e9d803dce
@ -1,7 +1,6 @@
|
||||
#importonce
|
||||
#import "../core/module.asm"
|
||||
#import "../libs/memory.asm"
|
||||
#import "../core/module.asm"
|
||||
|
||||
|
||||
.filenamespace Keyboard
|
||||
|
@ -145,6 +145,8 @@ init: {
|
||||
sta MemMap.VIDEO.CursorRow
|
||||
lda #%00000000
|
||||
sta MemMap.VIDEO.StatusBitsA
|
||||
lda #COLUMN_NUM
|
||||
sta MemMap.MATH.factor2
|
||||
rts
|
||||
}
|
||||
|
||||
@ -186,86 +188,80 @@ scrollUp: {
|
||||
// A = Character to Print VIDEO ASCII
|
||||
// --------------------------------------------------------
|
||||
sendChar: {
|
||||
sei
|
||||
phx
|
||||
cmp #CR
|
||||
bne !+
|
||||
jsr screenNewLine
|
||||
iny
|
||||
jmp exit
|
||||
!:
|
||||
cmp #BS
|
||||
bne !+
|
||||
ldx MemMap.VIDEO.CursorCol
|
||||
cmp #0
|
||||
beq exit
|
||||
dec MemMap.VIDEO.CursorCol
|
||||
!:
|
||||
// Store Base Video Address 16 bit
|
||||
ldx #<VIDEO_ADDR // Low byte
|
||||
stx MemMap.VIDEO.TempVideoPointer
|
||||
ldx #>VIDEO_ADDR // High byte
|
||||
stx MemMap.VIDEO.TempVideoPointer+1
|
||||
sei
|
||||
phx
|
||||
cmp #CR
|
||||
bne notCR
|
||||
jsr screenNewLine
|
||||
iny
|
||||
jmp exit
|
||||
|
||||
// Temp Save Y
|
||||
phy
|
||||
notCR:
|
||||
cmp #BS
|
||||
bne notBS
|
||||
ldx MemMap.VIDEO.CursorCol
|
||||
beq exit
|
||||
dec MemMap.VIDEO.CursorCol
|
||||
jmp storeBaseVideoAddress
|
||||
|
||||
// CursorRow * 40
|
||||
ldy MemMap.VIDEO.CursorRow
|
||||
sty MemMap.MATH.factor1
|
||||
ldy #COLUMN_NUM
|
||||
sty MemMap.MATH.factor2
|
||||
jsr Math.multiply
|
||||
notBS:
|
||||
// Store Base Video Address 16 bit
|
||||
storeBaseVideoAddress:
|
||||
ldx #<VIDEO_ADDR // Low byte
|
||||
stx MemMap.VIDEO.TempVideoPointer
|
||||
ldx #>VIDEO_ADDR // High byte
|
||||
stx MemMap.VIDEO.TempVideoPointer+1
|
||||
|
||||
// Add mul result to TempVideoPointer
|
||||
pha
|
||||
// CursorRow * 40
|
||||
ldy MemMap.VIDEO.CursorRow
|
||||
sty MemMap.MATH.factor1
|
||||
jsr Math.multiply
|
||||
|
||||
clc
|
||||
lda MemMap.MATH.result
|
||||
adc MemMap.VIDEO.TempVideoPointer+1
|
||||
sta MemMap.VIDEO.TempVideoPointer+1
|
||||
lda MemMap.MATH.result+1
|
||||
adc MemMap.VIDEO.TempVideoPointer
|
||||
sta MemMap.VIDEO.TempVideoPointer
|
||||
// Add mul result to TempVideoPointer
|
||||
pha
|
||||
clc
|
||||
lda MemMap.MATH.result
|
||||
adc MemMap.VIDEO.TempVideoPointer+1
|
||||
sta MemMap.VIDEO.TempVideoPointer+1
|
||||
lda MemMap.MATH.result+1
|
||||
adc MemMap.VIDEO.TempVideoPointer
|
||||
sta MemMap.VIDEO.TempVideoPointer
|
||||
|
||||
ldy MemMap.VIDEO.CursorCol
|
||||
cpy #COLUMN_NUM // Is this > col num?
|
||||
bcc noEndOfLine
|
||||
jsr screenNewLine // Yes? Add new line first
|
||||
ldy MemMap.VIDEO.CursorCol
|
||||
cpy #COLUMN_NUM // Is this > col num?
|
||||
bcc noEndOfLine
|
||||
jsr screenNewLine // Yes? Add new line first
|
||||
|
||||
bitTest(%00000001, MemMap.VIDEO.StatusBitsA)
|
||||
bne noScrollTriggered
|
||||
lda MemMap.VIDEO.StatusBitsA
|
||||
and #%00000001
|
||||
beq noScrollTriggered
|
||||
|
||||
// Compensate Scroll
|
||||
sec
|
||||
lda MemMap.VIDEO.TempVideoPointer
|
||||
sbc #40
|
||||
sta MemMap.VIDEO.TempVideoPointer
|
||||
bcs !+
|
||||
dec MemMap.VIDEO.TempVideoPointer+1
|
||||
!:
|
||||
// Compensate Scroll
|
||||
sec
|
||||
lda MemMap.VIDEO.TempVideoPointer
|
||||
sbc #40
|
||||
sta MemMap.VIDEO.TempVideoPointer
|
||||
bcs noScrollTriggered
|
||||
dec MemMap.VIDEO.TempVideoPointer+1
|
||||
|
||||
noScrollTriggered:
|
||||
noEndOfLine:
|
||||
pla
|
||||
// This is a backspace
|
||||
cmp #BS
|
||||
bne !+
|
||||
lda #' '
|
||||
sta (MemMap.VIDEO.TempVideoPointer), y
|
||||
ply
|
||||
jmp exit
|
||||
!:
|
||||
// insert into screen
|
||||
sta (MemMap.VIDEO.TempVideoPointer), y
|
||||
ply
|
||||
iny
|
||||
inc MemMap.VIDEO.CursorCol
|
||||
noScrollTriggered:
|
||||
noEndOfLine:
|
||||
pla
|
||||
cmp #BS
|
||||
bne notBackspace
|
||||
lda #' '
|
||||
sta (MemMap.VIDEO.TempVideoPointer), y
|
||||
jmp exit
|
||||
|
||||
exit:
|
||||
plx
|
||||
cli
|
||||
rts
|
||||
notBackspace:
|
||||
sta (MemMap.VIDEO.TempVideoPointer), y
|
||||
iny
|
||||
inc MemMap.VIDEO.CursorCol
|
||||
|
||||
exit:
|
||||
plx
|
||||
cli
|
||||
rts
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
@ -1,39 +1,45 @@
|
||||
#importonce
|
||||
.filenamespace Vic
|
||||
|
||||
// VIC registers and constants
|
||||
// For more information, refer to:
|
||||
// https://www.c64-wiki.com/wiki/VIC
|
||||
// https://www.c64-wiki.com/wiki/Page_208-211
|
||||
|
||||
// ========================================================
|
||||
// ////// CONSTANTS ///////////////////////////////////////
|
||||
// ========================================================
|
||||
// Base address for VIC registers
|
||||
.label VICREG = $D000
|
||||
|
||||
.label VICREG = $D000
|
||||
// Control register 2
|
||||
.label CR2 = $D016
|
||||
|
||||
.label CR2 = $D016 // Control register 2
|
||||
.label INTE = $D01A // Interrupt enabled
|
||||
.label RCNT = $D012 // Raster counter
|
||||
// Interrupt enabled register
|
||||
.label INTE = $D01A
|
||||
|
||||
// Raster counter register
|
||||
.label RCNT = $D012
|
||||
|
||||
|
||||
* = * "VIC Functions"
|
||||
|
||||
// Initialize the VIC registers with values from the tvic array
|
||||
init: {
|
||||
ldx #47
|
||||
px4:
|
||||
lda tvic-1, x
|
||||
sta VICREG-1, x
|
||||
dex
|
||||
bne px4
|
||||
rts
|
||||
ldx #47 // Set index to 47 (the number of bytes in tvic)
|
||||
load_loop: // Start of loop to load tvic values into VIC registers
|
||||
lda tvic-1, x // Load the byte from tvic at position x into the accumulator
|
||||
sta VICREG-1, x // Store the byte in the accumulator into the VIC register at position x
|
||||
dex // Decrement the index
|
||||
bne load_loop // If the index is not zero, repeat the loop
|
||||
rts // Return from subroutine
|
||||
}
|
||||
|
||||
* = * "VIC Init Data"
|
||||
|
||||
// Initial values for the VIC registers
|
||||
tvic:
|
||||
// The following bytes are loaded into the VIC registers in the init subroutine
|
||||
.byte $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byte $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byte $00, $9B, $37, $00, $00, $00, $08, $00
|
||||
.byte $14, $0F, $00, $00 ,$00, $00, $00, $00
|
||||
.byte $0E, $06, $01, $02, $03, $04, $00, $01
|
||||
.byte $02, $03, $04, $05, $06, $07, $4C
|
||||
|
||||
|
@ -123,30 +123,31 @@ toDebug: {
|
||||
// copy
|
||||
// --------------------------------------------------------
|
||||
clone: {
|
||||
phr
|
||||
sei
|
||||
ldy #0
|
||||
ldx MemMap.MEMORY.size
|
||||
beq md2
|
||||
md1: lda (MemMap.MEMORY.from),y // move a page at a time
|
||||
sta (MemMap.MEMORY.dest),y
|
||||
iny
|
||||
bne md1
|
||||
inc MemMap.MEMORY.from+1
|
||||
inc MemMap.MEMORY.dest+1
|
||||
dex
|
||||
bne md1
|
||||
md2: ldx MemMap.MEMORY.size+1
|
||||
beq md4
|
||||
md3: lda (MemMap.MEMORY.from),y // move the remaining bytes
|
||||
sta (MemMap.MEMORY.dest),y
|
||||
iny
|
||||
dex
|
||||
bne md3
|
||||
cli
|
||||
md4:
|
||||
plr
|
||||
rts
|
||||
phr
|
||||
sei
|
||||
ldy #0
|
||||
ldx MemMap.MEMORY.size
|
||||
beq checkHighByte
|
||||
md1:
|
||||
lda (MemMap.MEMORY.from),y // move a page at a time
|
||||
sta (MemMap.MEMORY.dest),y
|
||||
iny
|
||||
bne md1
|
||||
inc MemMap.MEMORY.from+1
|
||||
inc MemMap.MEMORY.dest+1
|
||||
dex
|
||||
bne md1
|
||||
checkHighByte:
|
||||
ldx MemMap.MEMORY.size+1
|
||||
md3:
|
||||
lda (MemMap.MEMORY.from),y // move the remaining bytes
|
||||
sta (MemMap.MEMORY.dest),y
|
||||
iny
|
||||
dex
|
||||
bne md3
|
||||
cli
|
||||
plr
|
||||
rts
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
@ -161,29 +162,22 @@ clone: {
|
||||
// A = The byte to fill memory with
|
||||
// --------------------------------------------------------
|
||||
fill: {
|
||||
phr
|
||||
sei
|
||||
ldy #0
|
||||
ldx MemMap.MEMORY.size
|
||||
beq md2
|
||||
md1:
|
||||
sta (MemMap.MEMORY.dest),y
|
||||
iny
|
||||
bne md1
|
||||
inc MemMap.MEMORY.dest+1
|
||||
dex
|
||||
bne md1
|
||||
md2: ldx MemMap.MEMORY.size+1
|
||||
beq md4
|
||||
md3:
|
||||
sta (MemMap.MEMORY.dest),y
|
||||
iny
|
||||
dex
|
||||
bne md3
|
||||
cli
|
||||
md4:
|
||||
plr
|
||||
rts
|
||||
phr
|
||||
sei
|
||||
ldy #0
|
||||
ldx MemMap.MEMORY.size
|
||||
cpx MemMap.MEMORY.size+1
|
||||
stx MemMap.MEMORY.size+1
|
||||
fillLoop:
|
||||
sta (MemMap.MEMORY.dest),y
|
||||
iny
|
||||
bne fillLoop
|
||||
inc MemMap.MEMORY.dest+1
|
||||
dex
|
||||
bne fillLoop
|
||||
cli
|
||||
plr
|
||||
rts
|
||||
}
|
||||
|
||||
// Clear Memory with 0
|
||||
|
@ -87,6 +87,10 @@ printLine: {
|
||||
rts
|
||||
}
|
||||
|
||||
|
||||
// Hexadecimal lookup table
|
||||
hexTable: .text "0123456789ABCDEF"
|
||||
|
||||
// --------------------------------------------------------
|
||||
// byteToHex -
|
||||
// Convert a byte to an HEX value
|
||||
@ -98,23 +102,22 @@ printLine: {
|
||||
// A = msn ascii char result
|
||||
// X = lns ascii char result
|
||||
// --------------------------------------------------------
|
||||
byteToHex: {
|
||||
pha
|
||||
jsr !+
|
||||
tax
|
||||
pla
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
|
||||
!: and #$0f
|
||||
cmp #$0a
|
||||
bcc !+
|
||||
adc #6
|
||||
|
||||
!: adc #'0'
|
||||
rts
|
||||
byteToHex: {
|
||||
tay // Save the original byte in Y
|
||||
and #$0F // Mask the lower 4 bits (nibble)
|
||||
tax // Transfer the lower nibble to X register
|
||||
lda hexTable, x // Load the ASCII value of the least significant hex digit
|
||||
tya // Restore the original byte from Y
|
||||
lsr // Shift the upper 4 bits (nibble) to the right
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
tax // Transfer the upper nibble to X register
|
||||
pha // Push the ASCII value of the least significant hex digit to stack
|
||||
lda hexTable, x // Load the ASCII value of the most significant hex digit
|
||||
tax // Transfer the ASCII value of the most significant hex digit to X
|
||||
pla // Pop the ASCII value of the least significant hex digit from stack to A
|
||||
rts // Return from the function // Return from the function
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
@ -45,26 +45,33 @@ toDebug: {
|
||||
// MemMap.MATH.result = 16 bit result
|
||||
// --------------------------------------------------------
|
||||
delayOne: {
|
||||
pha
|
||||
lda #$00
|
||||
sta MemMap.TIMERS.counter
|
||||
loop1: lda #$fb // wait for vertical retrace
|
||||
loop2: cmp $d012 // until it reaches 251th raster line ($fb)
|
||||
bne loop2 // which is out of the inner screen area
|
||||
inc MemMap.TIMERS.counter // increase frame counter
|
||||
lda MemMap.TIMERS.counter // check if counter
|
||||
cmp #$32 // reached 50
|
||||
bne out // if not, pass the color changing routine
|
||||
jmp exit
|
||||
pha
|
||||
lda #$00
|
||||
sta MemMap.TIMERS.counter
|
||||
|
||||
out:
|
||||
lda $d012 // make sure we reached
|
||||
loop3: cmp $d012 // the next raster line so next time we
|
||||
beq loop3
|
||||
jmp loop1 // jump to main loop
|
||||
exit:
|
||||
pla
|
||||
rts
|
||||
loop1:
|
||||
lda #$fb // wait for vertical retrace
|
||||
|
||||
loop2:
|
||||
cmp $d012 // until it reaches 251th raster line ($fb)
|
||||
beq waitForNextLine
|
||||
jmp loop2 // loop back if not yet at the 251th raster line
|
||||
|
||||
waitForNextLine:
|
||||
lda $d012 // make sure we reached
|
||||
|
||||
loop3:
|
||||
cmp $d012 // the next raster line so next time we
|
||||
beq loop1 // jump back to the main loop if still on the same raster line
|
||||
|
||||
inc MemMap.TIMERS.counter // increase frame counter
|
||||
lda MemMap.TIMERS.counter // check if counter
|
||||
cmp #$32 // reached 50
|
||||
bne loop1 // if not, jump back to the main loop
|
||||
|
||||
exit:
|
||||
pla
|
||||
rts
|
||||
}
|
||||
|
||||
|
||||
|
2
main.asm
2
main.asm
@ -1,6 +1,6 @@
|
||||
.cpu _6502
|
||||
|
||||
BasicUpstart2(Boot.warmStart)
|
||||
//BasicUpstart2(Boot.warmStart)
|
||||
#import "./hardware/mem_map.asm"
|
||||
|
||||
* = $8000 "Main"
|
||||
|
30
makefile
30
makefile
@ -1,22 +1,28 @@
|
||||
BUILD_PATH = ./bin
|
||||
KICKASS_BIN = /opt/develop/stid/c64/KickAssembler/KickAss.jar
|
||||
KICKASS_BIN = /Applications/KickAssembler/KickAss.jar
|
||||
PRG_FILE = ${BUILD_PATH}/main.prg
|
||||
CRT_FILE = ${BUILD_PATH}/woz.crt
|
||||
|
||||
.PHONY: all build eprom clean run
|
||||
|
||||
all: build
|
||||
|
||||
build:
|
||||
java -jar ${KICKASS_BIN} -odir ${BUILD_PATH} -log ${BUILD_PATH}/buildlog.txt -showmem ./main.asm
|
||||
cartconv -t normal -name "woz" -i ${BUILD_PATH}/main.prg -o ${BUILD_PATH}/woz.crt
|
||||
build: ${PRG_FILE} ${CRT_FILE}
|
||||
|
||||
eprom:
|
||||
java -jar ${KICKASS_BIN} -odir ${BUILD_PATH} -log ${BUILD_PATH}/buildlog.txt -showmem ./main.asm
|
||||
cartconv -t normal -name "woz" -i ${BUILD_PATH}/main.prg -o ${BUILD_PATH}/woz.crt
|
||||
cartconv -i ${BUILD_PATH}/woz.crt -o ${BUILD_PATH}/woz.bin
|
||||
eprom: ${PRG_FILE} ${CRT_FILE}
|
||||
cartconv -i ${CRT_FILE} -o ${BUILD_PATH}/woz.bin
|
||||
|
||||
clean:
|
||||
rm -Rf ./bin
|
||||
rm -Rf $(BUILD_PATH)
|
||||
|
||||
run:
|
||||
run: build
|
||||
x64sc $(CRT_FILE)
|
||||
|
||||
${BUILD_PATH}:
|
||||
mkdir -p $(BUILD_PATH)
|
||||
|
||||
${PRG_FILE}: ${BUILD_PATH}
|
||||
java -jar ${KICKASS_BIN} -odir ${BUILD_PATH} -log ${BUILD_PATH}/buildlog.txt -showmem ./main.asm
|
||||
cartconv -t normal -name "woz" -i ${BUILD_PATH}/main.prg -o ${BUILD_PATH}/woz.crt
|
||||
x64sc ${BUILD_PATH}/woz.crt
|
||||
|
||||
${CRT_FILE}: ${PRG_FILE}
|
||||
cartconv -t normal -n "woz" -i $(PRG_FILE) -o $(CRT_FILE)
|
Loading…
x
Reference in New Issue
Block a user