From 6e9d803dcea20479957329c454d1755396c4dbbb Mon Sep 17 00:00:00 2001 From: Stefano Furiosi Date: Sun, 2 Jul 2023 21:10:00 -0700 Subject: [PATCH] feat: optimizations --- devices/keyboard.asm | 1 - devices/video.asm | 138 +++++++++++++++++++++---------------------- hardware/vic.asm | 36 ++++++----- libs/memory.asm | 88 +++++++++++++-------------- libs/print.asm | 37 ++++++------ libs/timers.asm | 45 ++++++++------ main.asm | 2 +- makefile | 30 ++++++---- 8 files changed, 194 insertions(+), 183 deletions(-) diff --git a/devices/keyboard.asm b/devices/keyboard.asm index caa578e..6a654f3 100644 --- a/devices/keyboard.asm +++ b/devices/keyboard.asm @@ -1,7 +1,6 @@ #importonce #import "../core/module.asm" #import "../libs/memory.asm" -#import "../core/module.asm" .filenamespace Keyboard diff --git a/devices/video.asm b/devices/video.asm index 885dde7..b87195e 100644 --- a/devices/video.asm +++ b/devices/video.asm @@ -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 // 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 // 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 } // -------------------------------------------------------- diff --git a/hardware/vic.asm b/hardware/vic.asm index 0cb3519..f9c00f0 100644 --- a/hardware/vic.asm +++ b/hardware/vic.asm @@ -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 - diff --git a/libs/memory.asm b/libs/memory.asm index 3936e03..f6a3269 100644 --- a/libs/memory.asm +++ b/libs/memory.asm @@ -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 diff --git a/libs/print.asm b/libs/print.asm index 0d59111..426df38 100644 --- a/libs/print.asm +++ b/libs/print.asm @@ -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 } // -------------------------------------------------------- diff --git a/libs/timers.asm b/libs/timers.asm index dca1bf1..5298511 100644 --- a/libs/timers.asm +++ b/libs/timers.asm @@ -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 } diff --git a/main.asm b/main.asm index 4adaa6d..75c42bc 100644 --- a/main.asm +++ b/main.asm @@ -1,6 +1,6 @@ .cpu _6502 -BasicUpstart2(Boot.warmStart) +//BasicUpstart2(Boot.warmStart) #import "./hardware/mem_map.asm" * = $8000 "Main" diff --git a/makefile b/makefile index 55e3bdc..2187065 100644 --- a/makefile +++ b/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) \ No newline at end of file