diff --git a/keyb2.asm b/keyb2.asm index fbd775b..563cd75 100644 --- a/keyb2.asm +++ b/keyb2.asm @@ -10,7 +10,7 @@ .const cSYS_DelayValue = 32 .const cKeybW_Row1 = $FE -init: +init: { lda #64 sta MemMap.KEYB2.SYS_Lstx sta MemMap.KEYB2.SYS_Sfdx @@ -31,24 +31,9 @@ init: sta MemMap.KEYB2.SYS_Xmax // CLODE TO RAM - lda #cloneStart - sta MemMap.MEMORY.from+1 - - lda #<$1000 - sta MemMap.MEMORY.to - lda #>$1000 - sta MemMap.MEMORY.to+1 - - lda #cloneEnd-ReadKeyb - sta MemMap.MEMORY.size - - jsr Memory.clone - + clone(cloneStart, cloneEnd, $1000) rts +} KeyMapVec: .word KeyMap1, KeyMap2, KeyMap3, KeyMap4 @@ -259,8 +244,10 @@ GetKey: lda MemMap.KEYB2.SYS_Ndx tya clc rts +} +* = * "Keyb: cloneEnd" + cloneEnd: -} \ No newline at end of file diff --git a/main.asm b/main.asm index bbb647f..1ac28e2 100644 --- a/main.asm +++ b/main.asm @@ -1,4 +1,4 @@ -///BasicUpstart2(start) +BasicUpstart2(start) * = $8000 "Main" @@ -54,9 +54,8 @@ Raster: cmp $D012 jsr Screen.screenNewLine jsr Shell.clear jmp loop -inputChar: +inputChar: jsr Shell.push - jsr Screen.petToScreen cPrint() diff --git a/mem_map.asm b/mem_map.asm index 4f24023..423118a 100644 --- a/mem_map.asm +++ b/mem_map.asm @@ -11,14 +11,16 @@ .label CursorRow = ZPAGE_BASE+5 // 1 byte .label tempY = ZPAGE_BASE+6 // 1 byte .label tempX = ZPAGE_BASE+7 // 1 byte - .label cTempY = ZPAGE_BASE+8 // 1 byte + .label PrintPetCharY = ZPAGE_BASE+8 // 1 byte + .label PrintPetCharX = ZPAGE_BASE+9 // 1 byte + .label ScrollUpTriggered = ZPAGE_BASE+10 // 1 byte } .namespace MATH { - .label factor1 = ZPAGE_BASE+9 // 1 byte - .label factor2 = ZPAGE_BASE+10 // 1 byte - .label multiTmpX = ZPAGE_BASE+11 // 1 byte - .label result = ZPAGE_BASE+12 // 2 bytes + .label factor1 = ZPAGE_BASE+11 // 1 byte + .label factor2 = ZPAGE_BASE+12 // 1 byte + .label multiTmpX = ZPAGE_BASE+13 // 1 byte + .label result = ZPAGE_BASE+14 // 2 bytes } .namespace KEYB2 { @@ -36,7 +38,7 @@ .namespace MEMORY { .label from = ZPAGE_BASE+56 // 2 bytes - .label to = ZPAGE_BASE+58 // 2 bytes + .label dest = ZPAGE_BASE+58 // 2 bytes .label size = ZPAGE_BASE+60 // 2 bytes } @@ -46,8 +48,8 @@ .label L = ZPAGE_BASE+64 // 1 bytes .label H = ZPAGE_BASE+65 // 1 bytes .label YSAV = ZPAGE_BASE+66 // 1 bytes - .label STL = ZPAGE_BASE+67 // 1 bytes - .label STH = ZPAGE_BASE+68 // 1 bytes + .label STL = ZPAGE_BASE+67 // 1 bytes + .label STH = ZPAGE_BASE+68 // 1 bytes .label XAML = ZPAGE_BASE+69 // 1 bytes .label XAMH = ZPAGE_BASE+70 // 1 bytes diff --git a/memory.asm b/memory.asm index 2217d6a..41307d2 100644 --- a/memory.asm +++ b/memory.asm @@ -1,33 +1,55 @@ #importonce -.filenamespace Memory #import "mem_map.asm" * = * "Memory Routines" +.macro clone(from, to, dest) { + lda #from + sta MemMap.MEMORY.from+1 + + lda #dest + sta MemMap.MEMORY.dest+1 + + lda #to-from + sta MemMap.MEMORY.size + + jsr Memory._clone +} + +.filenamespace Memory + + // move memory down // // from = source start address // to = destination start address // size = number of bytes to move // -clone: +_clone: { ldy #0 ldx MemMap.MEMORY.size beq md2 md1: lda (MemMap.MEMORY.from),y // move a page at a time - sta (MemMap.MEMORY.to),y + sta (MemMap.MEMORY.dest),y iny bne md1 inc MemMap.MEMORY.from+1 - inc MemMap.MEMORY.to+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.to),y + sta (MemMap.MEMORY.dest),y iny dex bne md3 md4: rts +} \ No newline at end of file diff --git a/screen.asm b/screen.asm index 2af1e5e..72932cd 100644 --- a/screen.asm +++ b/screen.asm @@ -1,6 +1,7 @@ #importonce #import "math.asm" #import "mem_map.asm" +#import "memory.asm" // ----------------------- // MACROS @@ -15,53 +16,51 @@ } .macro cPrint() { - sty MemMap.SCREEN.cTempY - jsr Screen.printChar - ldy MemMap.SCREEN.cTempY + jsr Screen.printPetChar } .macro ClearScreen(screen, clearByte) { - lda #clearByte - ldx #0 + lda #clearByte + ldx #0 !loop: - sta screen, x - sta screen + $100, x - sta screen + $200, x - sta screen + $300, x + sta screen, x + sta screen + $100, x + sta screen + $200, x + sta screen + $300, x inx - bne.r !loop- + bne.r !loop- } .macro ClearColorRam(clearByte) { - lda #clearByte - ldx #0 + lda #clearByte + ldx #0 !loop: - sta $D800, x - sta $D800 + $100, x - sta $D800 + $200, x - sta $D800 + $300, x + sta $D800, x + sta $D800 + $100, x + sta $D800 + $200, x + sta $D800 + $300, x inx - bne.r !loop- + bne.r !loop- } .macro SetBorderColor(color) { - lda #color - sta $d020 + lda #color + sta $d020 } .macro SetBackgroundColor(color) { - lda #color - sta $d021 + lda #color + sta $d021 } .macro SetMultiColor1(color) { - lda #color - sta $d022 + lda #color + sta $d022 } .macro SetMultiColor2(color) { - lda #color - sta $d023 + lda #color + sta $d023 } .macro SetMultiColorMode() { @@ -71,9 +70,9 @@ } .macro SetScrollMode() { - lda $D016 - eor #%00001000 - sta $D016 + lda $D016 + eor #%00001000 + sta $D016 } .filenamespace Screen @@ -83,11 +82,9 @@ // CONSTANTS // ----------------------- -.namespace constants { - .label VIDEO_ADDR = $0400 - .label COLUMN_NUM = 40 - .label ROWS_NUM = 25 -} +.const VIDEO_ADDR = $0400 +.const COLUMN_NUM = 40 +.const ROWS_NUM = 25 // ----------------------- @@ -95,66 +92,107 @@ // ----------------------- init: { - lda #$00 - sta MemMap.SCREEN.CursorCol - sta MemMap.SCREEN.CursorRow - rts + lda #$00 + sta MemMap.SCREEN.CursorCol + sta MemMap.SCREEN.CursorRow + rts +} + +scrollUp: { + pha + clone(VIDEO_ADDR+40, VIDEO_ADDR+(COLUMN_NUM*(ROWS_NUM)), VIDEO_ADDR) + lda #32 + ldx #00 +!: + sta VIDEO_ADDR+(COLUMN_NUM*(ROWS_NUM-1)), x + inx + cpx #40 + bne !- + dec MemMap.SCREEN.CursorRow + pla + rts +} + +printPetChar: { + pha + stx MemMap.SCREEN.PrintPetCharX + sty MemMap.SCREEN.PrintPetCharY + jsr Screen.petToScreen + jsr Screen.printChar + ldy MemMap.SCREEN.PrintPetCharY + ldx MemMap.SCREEN.PrintPetCharX + pla + rts } printChar: { - stx MemMap.SCREEN.tempX + stx MemMap.SCREEN.tempX // New Line - cmp #$8e - bne.r !+ - jsr screenNewLine + cmp #$8e + bne.r !+ + jsr screenNewLine iny rts !: // Store Base Video Address 16 bit - ldx #constants.VIDEO_ADDR // High byte - stx MemMap.SCREEN.TempVideoPointer+1 + ldx #VIDEO_ADDR // High byte + stx MemMap.SCREEN.TempVideoPointer+1 // Temp Save Y - sty MemMap.SCREEN.tempY + sty MemMap.SCREEN.tempY // CursorRow * 40 - ldy MemMap.SCREEN.CursorRow - sty MemMap.MATH.factor1 - ldy #constants.COLUMN_NUM - sty MemMap.MATH.factor2 - jsr Math.multiply + ldy MemMap.SCREEN.CursorRow + sty MemMap.MATH.factor1 + ldy #COLUMN_NUM + sty MemMap.MATH.factor2 + jsr Math.multiply // Add mul result to TempVideoPointer clc pha - lda MemMap.MATH.result - adc MemMap.SCREEN.TempVideoPointer+1 - sta MemMap.SCREEN.TempVideoPointer+1 - lda MemMap.MATH.result+1 - adc MemMap.SCREEN.TempVideoPointer - sta MemMap.SCREEN.TempVideoPointer + lda MemMap.MATH.result + adc MemMap.SCREEN.TempVideoPointer+1 + sta MemMap.SCREEN.TempVideoPointer+1 + lda MemMap.MATH.result+1 + adc MemMap.SCREEN.TempVideoPointer + sta MemMap.SCREEN.TempVideoPointer + + ldy MemMap.SCREEN.CursorCol + cpy #COLUMN_NUM // Is this > col num? + bcc.r noEndOfLine + jsr screenNewLine // Yes? Add new list first + + ldy #1 + cpy MemMap.SCREEN.ScrollUpTriggered + bne noScrollTriggered + .break + + // Compesat Scroll + sec + lda MemMap.SCREEN.TempVideoPointer + sbc #1 + sta MemMap.SCREEN.TempVideoPointer + bcs !+ + dec MemMap.SCREEN.TempVideoPointer+1 + !: + + +noScrollTriggered: +noEndOfLine: pla - // Add column - ldy MemMap.SCREEN.CursorCol - sta (MemMap.SCREEN.TempVideoPointer), y - - ldy MemMap.SCREEN.tempY + // insert into screen + sta (MemMap.SCREEN.TempVideoPointer), y + ldy MemMap.SCREEN.tempY iny + inc MemMap.SCREEN.CursorCol - inc MemMap.SCREEN.CursorCol - lda MemMap.SCREEN.CursorCol - cmp #constants.COLUMN_NUM+1 - bcc.r exita - - // CursorCol > COLUMN_NUM ? new line - jsr screenNewLine -exita: - ldx MemMap.SCREEN.tempX +exit: + ldx MemMap.SCREEN.tempX rts - } @@ -168,23 +206,37 @@ exita: // returned values: none // —————————————————————————————————————————————————————— print: { - ldy #$00 - sta MemMap.SCREEN.TempStringPointer - stx MemMap.SCREEN.TempStringPointer+1 + ldy #$00 + sta MemMap.SCREEN.TempStringPointer + stx MemMap.SCREEN.TempStringPointer+1 printLoop: - lda (MemMap.SCREEN.TempStringPointer), y - cmp #0 - beq exit - jsr Screen.printChar - jmp printLoop + lda (MemMap.SCREEN.TempStringPointer), y + cmp #0 + beq exit + jsr Screen.printChar + jmp printLoop exit: rts } screenNewLine: { - lda #0 - sta MemMap.SCREEN.CursorCol - inc MemMap.SCREEN.CursorRow + pha + lda #0 + sta MemMap.SCREEN.CursorCol + lda #ROWS_NUM-1 + cmp MemMap.SCREEN.CursorRow // Are we at the screen bottom? + bne noScrollUp + jsr Screen.scrollUp + lda #1 // Yes - Scroll up + sta MemMap.SCREEN.ScrollUpTriggered + jmp done + +noScrollUp: + lda #0 + sta MemMap.SCREEN.ScrollUpTriggered +done: + inc MemMap.SCREEN.CursorRow + pla rts } @@ -199,65 +251,55 @@ screenNewLine: { // ———————————————————————————————————————— petToScreen: { // $00-$1F - cmp #$1f - bcs !+ - sec - adc #128 - jmp convDone - + cmp #$1f + bcs !+ + sec + adc #128 + jmp convDone // $20-$3F !: - cmp #$3f - bcs !+ - jmp convDone - + cmp #$3f + bcs !+ + jmp convDone // $40-$5F !: - cmp #$5f - bcs !+ - sec - sbc #$40 - jmp convDone - - + cmp #$5f + bcs !+ + sec + sbc #$40 + jmp convDone // $60-$7F !: - cmp #$7F - bcs !+ - sec - sbc #32 - jmp convDone - + cmp #$7F + bcs !+ + sec + sbc #32 + jmp convDone // $80-$9F !: - cmp #$9F - bcs !+ - sec - adc #64 - jmp convDone + cmp #$9F + bcs !+ + sec + adc #64 + jmp convDone // $A0-$BF !: - cmp #$BF - bcs !+ - sec - sbc #64 - jmp convDone - + cmp #$BF + bcs !+ + sec + sbc #64 + jmp convDone // $C0-$DF // $E0-$FE !: - cmp #$FE - bcs !+ - sec - sbc #128 - jmp convDone - + cmp #$FE + bcs !+ + sec + sbc #128 + jmp convDone // $FF !: - lda $5E - - + lda $5E convDone: - rts - + rts } \ No newline at end of file diff --git a/shell.asm b/shell.asm index d5ad4fe..3361099 100644 --- a/shell.asm +++ b/shell.asm @@ -8,7 +8,7 @@ .const CR = $0d - +clear: init: { lda #-1 sta MemMap.SHELL.pos @@ -16,45 +16,37 @@ init: { } push: { - ldy MemMap.SHELL.pos + ldy MemMap.SHELL.pos iny - cpy #127 - beq done - sty MemMap.SHELL.pos - sta MemMap.SHELL.buffer, y + cpy #127 + beq.r done + sty MemMap.SHELL.pos + sta MemMap.SHELL.buffer, y done: rts } -clear: { - ldy #-1 - sty MemMap.SHELL.pos - rts -} - // WOZ MONITOR FLOW - FROM APPLE1 wozExec: { - ldy #-1 - lda #0 + ldy #-1 + lda #0 tax - SETSTOR: asl - SETMODE: - cmp #0 - beq !+ - eor #%10000000 + SETMODE: + cmp #0 + beq.r !+ + eor #%10000000 !: - sta MemMap.SHELL.MODE + sta MemMap.SHELL.MODE BLSKIP: iny - NEXTITEM: - .break + NEXTITEM: lda MemMap.SHELL.buffer,Y //Get character - cmp #$0d - bne CONT // We're done if it's CR! + cmp #CR + bne.r CONT // We're done if it's CR! rts CONT: cmp #'.' @@ -70,8 +62,8 @@ wozExec: { // Here we're trying to parse a new hex value - NEXTHEX: - lda MemMap.SHELL.buffer,y // Get character for hex test + NEXTHEX: + lda MemMap.SHELL.buffer,y // Get character for hex test eor #$30 // Map digits to 0-9 cmp #9+1 // Is it a decimal digit? bcc DIG // Yes! @@ -79,27 +71,27 @@ wozExec: { cmp #$FA // Hex letter? bcc NOTHEX // No! Character not hex - DIG: + DIG: asl asl // Hex digit to MSD of A asl asl - ldx #4 // Shift count - HEXSHIFT: asl // Hex digit left, MSB to carry - rol MemMap.SHELL.L // Rotate into LSD - rol MemMap.SHELL.H // Rotate into MSD's - dex // Done 4 shifts? - bne HEXSHIFT // No, loop - iny // Advance text index - bne NEXTHEX // Always taken + ldx #4 // Shift count + HEXSHIFT: asl // Hex digit left, MSB to carry + rol MemMap.SHELL.L // Rotate into LSD + rol MemMap.SHELL.H // Rotate into MSD's + dex // Done 4 shifts? + bne HEXSHIFT // No, loop + iny // Advance text index + bne NEXTHEX // Always taken -NOTHEX: cpy MemMap.SHELL.YSAV //Was at least 1 hex digit given? +NOTHEX: cpy MemMap.SHELL.YSAV //Was at least 1 hex digit given? bne !+ // No! Ignore all, start from scratch rts !: - bit MemMap.SHELL.MODE //Test MODE byte - bvc NOTSTOR // B6=0 is STOR, 1 is XAM or BLOCK XAM + bit MemMap.SHELL.MODE //Test MODE byte + bvc NOTSTOR // B6=0 is STOR, 1 is XAM or BLOCK XAM // STOR mode, save LSD of new hex byte @@ -120,59 +112,59 @@ RUN: jmp (MemMap.SHELL.XAML) // Run user's program // We're not in Store mode //------------------------------------------------------------------------- -NOTSTOR: bmi XAMNEXT // B7 = 0 for XAM, 1 for BLOCK XAM +NOTSTOR: bmi XAMNEXT // B7 = 0 for XAM, 1 for BLOCK XAM // We're in XAM mode now - ldx #2 // Copy 2 bytes -SETADR: lda MemMap.SHELL.L-1,X // Copy hex data to - sta MemMap.SHELL.STL-1,X // 'store index' - sta MemMap.SHELL.XAML-1,X // and to 'XAM index' - dex // Next of 2 bytes - bne SETADR // Loop unless X = 0 + ldx #2 // Copy 2 bytes +SETADR: lda MemMap.SHELL.L-1,X // Copy hex data to + sta MemMap.SHELL.STL-1,X // 'store index' + sta MemMap.SHELL.XAML-1,X // and to 'XAM index' + dex // Next of 2 bytes + bne SETADR // Loop unless X = 0 // Print address and data from this address, fall through next BNE. -NXTPRNT: bne PRDATA // NE means no address to print - lda #$8e // Print CR first +NXTPRNT: bne PRDATA // NE means no address to print + lda #CR // Print CR first cPrint() - lda MemMap.SHELL.XAMH // Output high-order byte of address + lda MemMap.SHELL.XAMH // Output high-order byte of address jsr PRBYTE - lda MemMap.SHELL.XAML // Output low-order byte of address + lda MemMap.SHELL.XAML // Output low-order byte of address jsr PRBYTE - lda #':' // Print colon + lda #':' // Print colon cPrint() -PRDATA: lda #' ' // Print space +PRDATA: lda #' ' // Print space cPrint() lda (MemMap.SHELL.XAML,X) // Get data from address (X=0) - jsr PRBYTE // Output it in hex format -XAMNEXT: stx MemMap.SHELL.MODE // 0 -> MODE (XAM mode). - lda MemMap.SHELL.XAML // See if there's more to print + jsr PRBYTE // Output it in hex format +XAMNEXT: stx MemMap.SHELL.MODE // 0 -> MODE (XAM mode). + lda MemMap.SHELL.XAML // See if there's more to print cmp MemMap.SHELL.L lda MemMap.SHELL.XAMH sbc MemMap.SHELL.H - bcs TONEXTITEM // Not less! No more data to output + bcs TONEXTITEM // Not less! No more data to output inc MemMap.SHELL.XAML // Increment 'examine index' - bne MOD8CHK // No carry! + bne MOD8CHK // No carry! inc MemMap.SHELL.XAMH -MOD8CHK: lda MemMap.SHELL.XAML // If address MOD 8 = 0 start new line +MOD8CHK: lda MemMap.SHELL.XAML // If address MOD 8 = 0 start new line and #%00000111 - bpl NXTPRNT // Always taken. + bpl NXTPRNT // Always taken. // ------------------------------------------------------------------------- // Subroutine to print a byte in A in hex form (destructive) // ------------------------------------------------------------------------- -PRBYTE: pha // Save A for LSD +PRBYTE: pha // Save A for LSD lsr lsr - lsr // MSD to LSD position + lsr // MSD to LSD position lsr - jsr PRHEX // Output hex digit - pla // Restore A + jsr PRHEX // Output hex digit + pla // Restore A // Fall through to print hex routine @@ -180,12 +172,11 @@ PRBYTE: pha // Save A for LSD // Subroutine to print a hexadecimal digit // ------------------------------------------------------------------------- -PRHEX: and #%00001111 // Mask LSD for hex print - ora #'0' // Add "0" - cmp #'9'+1 // Is it a decimal digit? - bcc !+ // Yes! output it - adc #6 // Add offset for letter A-F - jsr Screen.petToScreen +PRHEX: and #%00001111 // Mask LSD for hex print + ora #'0' // Add "0" + cmp #'9'+1 // Is it a decimal digit? + bcc !+ // Yes! output it + adc #6 // Add offset for letter A-F !: cPrint() rts