diff --git a/arch/keyb.asm b/arch/keyb.asm deleted file mode 100644 index 50f0118..0000000 --- a/arch/keyb.asm +++ /dev/null @@ -1,747 +0,0 @@ -BasicUpstart2(start) - -// c64 -.const bgcolor = $d020 -.const bordercolor = $d021 -.const screenram = $0400 - -// kernel functions -.const bsout = $ab1e //kernel character output sub -.const chrout = $ffd2 -.const clearscreen = $e544 - -// chars -.const cr = 13 - -// memory map -.const kernel = $ff80 -.const start_basic = $0281 -.const end_basic = $0037 -.const step_size_garb = $000f -.const dataset = $0090 -.const input_dev = 153 -.const out_dev = 154 -.const time_1 = 160 -.const time_2 = 161 -.const time_3 = 162 -.const ds_motor = 192 - -// color petscii -.const color_cyan = $9f -.const color_light_blue = $9a -.const color_green = $1e - -// local const -.const pline_len = 40 -.const hex_open_chr = $5b -.const hex_close_chr = $5d - -.macro printHexByte(stringAddr, value) { - lda #stringAddr - ldx value - jsr printhex_row -} - -.macro printHexWord(stringAddr, value) { - bPrint(stringAddr) - jsr popenhex - lda value+1 - jsr printhex - lda value - jsr printhex - jsr pclosehex - bChar(cr) -} - -.macro bPrint(stringAddr) { - lda #stringAddr - jsr bsout -} - -.macro bChar(char) { - lda #char - jsr chrout -} - -//========================================================== -// code -//========================================================== - -start: - ldx #$00 // color - stx $d021 // set background color - stx $d020 // set border color - - jsr clearscreen - - bChar(color_cyan) - bPrint(str_about) - - bChar(cr) - bChar(color_light_blue) - -getKeyb: - jsr Keyboard - bcs NoValidInput - stx TempX - sty TempY - cmp #$ff - // Check A for Alphanumeric keys - beq NoNewAphanumericKey - // jsr printhex - - cmp #'m' - beq mapMemory - cmp #'q' - beq exit - - jmp getKeyb - -NoNewAphanumericKey: - // Check X & Y for Non-Alphanumeric Keys - ldx TempX - ldy TempY - //stx $0401 - //sty $0402 -NoValidInput: // This may be substituted for an errorhandler if needed. - jmp getKeyb - - -exit: rts - - -mapMemory: - ldx #pline_len // lenht of pline - jsr pline - - // ---------------------- - // ------ map table start - // ---------------------- - - // kernel - printHexByte(str_row_kernel, kernel) - - // start basic area - printHexWord(str_row_basic_start, start_basic) - - // end basic area - printHexWord(str_row_basic_end, end_basic) - - // garbadge - printHexByte(str_row_step_size_garb, printhex_row) - - // dataset - printHexByte(str_row_dataset, dataset) - - // input dev - printHexByte(str_row_input_dev, input_dev) - - // out dev - printHexByte(str_row_out_dev, out_dev) - - // time 1 - printHexByte(str_row_time_1, time_1) - - // time 2 - printHexByte(str_row_time_2, time_2) - - // time 2 - printHexByte(str_row_time_2, time_3) - - // dataset motor - printHexByte(str_row_ds_motor, ds_motor) - - - // ---------------------- - // ------ map table end - // ---------------------- - bChar(cr) - - ldx #pline_len - jsr pline - rts - -// ———————————————————————————————————— -// popenhex -// ———————————————————————————————————— -popenhex: - bChar(hex_open_chr) - bChar(color_green) - rts - -// ———————————————————————————————————— -// pclosehex -// ———————————————————————————————————— -pclosehex: - bChar(color_light_blue) - bChar(hex_close_chr) - rts - -// ———————————————————————————————————— -// printhex_row -// ———————————————————————————————————— -// ———————————————————————————————————— -// preparatory ops: .a: msn ascii char -// .x: lsn ascii char -// .y: value -// -// returned values: none -// ———————————————————————————————————— -printhex_row: - sta a_cache // preserve a - txa // store x using a as it will be lost after bsout - pha - lda a_cache // get back a - jsr bsout - jsr popenhex - pla // saved x back in a from saved a - jsr printhex - jsr pclosehex - bChar(cr) - rts - -// ———————————————————————————————————— -// printhex -// ———————————————————————————————————— -// ———————————————————————————————————— -// preparatory ops: .a: byte to convert -// -// returned values: none -// ———————————————————————————————————— -printhex: - pha - jsr binhex - jsr chrout - txa - jsr chrout - pla - rts - -// ———————————————————————————————————— -// btohex -// ———————————————————————————————————— -// ———————————————————————————————————— -// preparatory ops: .a: byte to convert -// -// returned values: .a: msn ascii char -// .x: lsn ascii char -// .y: entry value -// ———————————————————————————————————— -binhex: pha //save byte - and #%00001111 //extract lsn - tax //save it - pla //recover byte - lsr //extract... - lsr //msn - lsr - lsr - pha //save msn - txa //lsn - jsr binhex1 //generate ascii lsn - tax //save - pla //get msn & fall thru -// -// convert nybble to hex ascii equivalent... -binhex1: cmp #$0a - bcc binhex2 //in decimal range - adc #$66 //hex compensate -binhex2: eor #%00110000 //finalize nybble - rts //done - - - -// ———————————————————————————————————— -// pline -// ———————————————————————————————————— -// ———————————————————————————————————— -// preparatory ops: .x: lenght -// returned values: none -// ———————————————————————————————————— -pline: - cpx #0 - bne pline_start - ldx #12 // default to 12 if 0 is passed in x -pline_start: lda #102 -pline_loop: jsr chrout - dex - cpx #0 - bne pline_loop - lda #cr - jsr chrout - rts - - -.encoding "petscii_mixed" -str_about: - .text "c=64 mapper v2.0 by =stid=" - .byte 13, 0 -str_row_kernel: - .text " kernel " - .byte 0 -str_row_basic_start: - .text " start basic area " - .byte 0 -str_row_basic_end: - .text " end basic area " - .byte 0 -str_row_step_size_garb: - .text " step size garbage " - .byte 0 -str_row_dataset: - .text " dataset " - .byte 0 -str_row_input_dev: - .text " input device " - .byte 0 -str_row_out_dev: - .text " output device " - .byte 0 -str_row_time_1: - .text " time 1 " - .byte 0 -str_row_time_2: - .text " time 2 " - .byte 0 -str_row_time_3: - .text " time 3 " - .byte 0 -str_row_ds_motor: - .text " dataset motor " - .byte 0 - -a_cache: - .byte 0 - -TempX: - .byte 0 -TempY: - .byte 0 - - - - -/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Keyboard IO Routine - ~~~~~~~~~~~~~~~~~~~ - By: TWW/CTR - - - Preparatory Settings - ~~~~~~~~~~~~~~~~~~~~ - None - - - Destroys - ~~~~~~~~ - Accumulator - X-Register - Y-Register - Carry / Zero / Negative - $dc00 - $dc01 - $50-$5f - - - Footprint - ~~~~~~~~~ - #$206 Bytes - - - Information - ~~~~~~~~~~~ - The routine uses "2 Key rollower" or up to 3 if the key-combination doesen't induce shadowing. - If 2 or 3 keys are pressed simultaneously (within 1 scan) a "No Activity" state has to occur before new valid keys are returned. - RESTORE is not detectable and must be handled by NMI IRQ. - SHIFT LOCK is not detected due to unreliability. - - - Usage - ~~~~~ - Example Code: - - jsr Keyboard - bcs NoValidInput - stx TempX - sty TempY - cmp #$ff - beq NoNewAphanumericKey - // Check A for Alphanumeric keys - sta $0400 - NoNewAphanumericKey: - // Check X & Y for Non-Alphanumeric Keys - ldx TempX - ldy TempY - stx $0401 - sty $0402 - NoValidInput: // This may be substituted for an errorhandler if needed. - - - Returned - ~~~~~~~~ - - +=================================================+ - | Returned in Accumulator | - +===========+===========+=============+===========+ - | $00 - @ | $10 - p | $20 - SPC | $30 - 0 | - | $01 - a | $11 - q | $21 - | $31 - 1 | - | $02 - b | $12 - r | $22 - | $32 - 2 | - | $03 - c | $13 - s | $23 - | $33 - 3 | - | $04 - d | $14 - t | $24 - | $34 - 4 | - | $05 - e | $15 - u | $25 - | $35 - 5 | - | $06 - f | $16 - v | $26 - | $36 - 6 | - | $07 - g | $17 - w | $27 - | $37 - 7 | - | $08 - h | $18 - x | $28 - | $38 - 8 | - | $09 - i | $19 - y | $29 - | $39 - 9 | - | $0a - j | $1a - z | $2a - * | $3a - : | - | $0b - k | $1b - | $2b - + | $3b - ; | - | $0c - l | $1c - £ | $2c - , | $3c - | - | $0d - m | $1d - | $2d - - | $3d - = | - | $0e - n | $1e - ^ | $2e - . | $3e - | - | $0f - o | $1f - <- | $2f - / | $3f - | - +-----------+-----------+-------------+-----------+ - - +================================================================================ - | Return in X-Register | - +=========+=========+=========+=========+=========+=========+=========+=========+ - | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | - +---------+---------+---------+---------+---------+---------+---------+---------+ - | CRSR UD | F5 | F3 | F1 | F7 | CRSR RL | RETURN |INST/DEL | - +---------+---------+---------+---------+---------+---------+---------+---------+ - - +================================================================================ - | Return in Y-Register | - +=========+=========+=========+=========+=========+=========+=========+=========+ - | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | - +---------+---------+---------+---------+---------+---------+---------+---------+ - |RUN STOP | L-SHIFT | C= | R-SHIFT |CLR/HOME | CTRL | | | - +---------+---------+---------+---------+---------+---------+---------+---------+ - - CARRY: - - Set = Error Condition (Check A for code): - A = #$01 => No keyboard activity is detected. - A = #$02 => Control Port #1 Activity is detected. - A = #$03 => Key Shadowing / Ghosting is detected. - A = #$04 => 2 or 3 new keys is detected within one scan - A = #$05 => Awaiting "No Activity" state - - Clear = Valid input - A = #$ff => No new Alphanumeric Keys detected (some key(s) being held down AND/OR some Non-Alphanumeric key is causing valid return). - A <> #$ff => New Alphanumeric Key returned. Non-Alphanumeric keys may also be returned in X or Y Register - - Issues/ToDo: - ~~~~~~~~~~~~ - - None - - - Improvements: - ~~~~~~~~~~~~~ - - Replace the subroutine with a pseudocommand and account for speedcode parameter (Memory vs. Cycles). - - Shorten the routine / Optimize if possible. - - - History: - ~~~~~~~~ - V2.5 - New test tool. - Added return of error codes. - Fixed a bug causing Buffer Overflow. - Fixed a bug in Non Alphanumerical Flags from 2.0. - V2.1 - Shortened the source by adding .for loops & Updated the header and some comments. - Added "simultaneous keypress" check. - V2.0 - Added return of non-Alphanumeric keys into X & Y-Registers. - Small optimizations here and there. - V1.1 - Unrolled code to make it faster and optimized other parts of it. - Removed SHIFT LOCK scanning. - V1.0 - First Working Version along with test tool. - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - - * = * "Keyboard Scan Routine" - - - // ZERO PAGE Varibles - .const ScanResult = $50 // 8 bytes - .const BufferNew = $58 // 3 bytes - .const KeyQuantity = $5b // 1 byte - .const NonAlphaFlagX = $5c // 1 byte - .const NonAlphaFlagY = $5d // 1 byte - .const TempZP = $5e // 1 byte - .const SimultaneousKeys = $5f // 1 byte - - // Operational Variables - .var MaxKeyRollover = 3 - -Keyboard: -{ - jmp Main - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Routine for Scanning a Matrix Row - -KeyInRow: - asl - bcs *+5 - jsr KeyFound - .for (var i = 0 ; i < 7 ; i++) { - inx - asl - bcs *+5 - jsr KeyFound - } - rts - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Routine for handling: Key Found - -KeyFound: - stx TempZP - dec KeyQuantity - bmi OverFlow - ldy KeyTable,x - ldx KeyQuantity - sty BufferNew,x - ldx TempZP - rts - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Routine for handling: Overflow - -OverFlow: - pla // Dirty hack to handle 2 layers of JSR - pla - pla - pla - // Don't manipulate last legal buffer as the routine will fix itself once it gets valid input again. - lda #$03 - sec - rts - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Exit Routine for: No Activity - -NoActivityDetected: - // Exit With A = #$01, Carry Set & Reset BufferOld. - lda #$00 - sta SimultaneousAlphanumericKeysFlag // Clear the too many keys flag once a "no activity" state is detected. - stx BufferOld - stx BufferOld+1 - stx BufferOld+2 - sec - lda #$01 - rts - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Exit Routine for Control Port Activity - -ControlPort: - // Exit with A = #$02, Carry Set. Keep BufferOld to verify input after Control Port activity ceases - sec - lda #$02 - rts - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Configure Data Direction Registers -Main: - ldx #$ff - stx $dc02 // Port A - Output - ldy #$00 - sty $dc03 // Port B - Input - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Check for Port Activity - - sty $dc00 // Connect all Keyboard Rows - cpx $dc01 - beq NoActivityDetected - - lda SimultaneousAlphanumericKeysFlag - beq !+ - // Waiting for all keys to be released before accepting new input. - lda #$05 - sec - rts -!: - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Check for Control Port #1 Activity - - stx $dc00 // Disconnect all Keyboard Rows - cpx $dc01 // Only Control Port activity will be detected - bne ControlPort - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Scan Keyboard Matrix - - lda #%11111110 - sta $dc00 - ldy $dc01 - sty ScanResult+7 - sec - .for (var i = 6 ; i > -1 ; i--) { - rol - sta $dc00 - ldy $dc01 - sty ScanResult+i - } - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Check for Control Port #1 Activity (again) - - stx $dc00 // Disconnect all Keyboard Rows - cpx $dc01 // Only Control Port activity will be detected - bne ControlPort - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Initialize Buffer, Flags and Max Keys - - // Reset current read buffer - stx BufferNew - stx BufferNew+1 - stx BufferNew+2 - - // Reset Non-AlphaNumeric Flag - inx - stx NonAlphaFlagY - - // Set max keys allowed before ignoring result - lda #MaxKeyRollover - sta KeyQuantity - - // Counter to check for simultaneous alphanumeric key-presses - lda #$fe - sta SimultaneousKeys - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Check and flag Non Alphanumeric Keys - - lda ScanResult+6 - eor #$ff - and #%10000000 // Left Shift - lsr - sta NonAlphaFlagY - lda ScanResult+0 - eor #$ff - and #%10100100 // RUN STOP - C= - CTRL - ora NonAlphaFlagY - sta NonAlphaFlagY - lda ScanResult+1 - eor #$ff - and #%00011000 // Right SHIFT - CLR HOME - ora NonAlphaFlagY - sta NonAlphaFlagY - - lda ScanResult+7 // The rest - eor #$ff - sta NonAlphaFlagX - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Check for pressed key(s) - - lda ScanResult+7 - cmp #$ff - beq *+5 - jsr KeyInRow - .for (var i = 6 ; i > -1 ; i--) { - ldx #[7-i]*8 - lda ScanResult+i - beq *+5 - jsr KeyInRow - } - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Key Scan Completed - - // Put any new key (not in old scan) into buffer - ldx #MaxKeyRollover-1 - !: lda BufferNew,x - cmp #$ff - beq Exist // Handle 'null' values - cmp BufferOld - beq Exist - cmp BufferOld+1 - beq Exist - cmp BufferOld+2 - beq Exist - // New Key Detected - inc BufferQuantity - ldy BufferQuantity - sta Buffer,y - // Keep track of how many new Alphanumeric keys are detected - inc SimultaneousKeys - beq TooManyNewKeys - Exist: - dex - bpl !- - - // Anything in Buffer? - ldy BufferQuantity - bmi BufferEmpty - // Yes: Then return it and tidy up the buffer - dec BufferQuantity - lda Buffer - ldx Buffer+1 - stx Buffer - ldx Buffer+2 - stx Buffer+1 - jmp Return - -BufferEmpty: // No new Alphanumeric keys to handle. - lda #$ff - -Return: // A is preset - clc - // Copy BufferNew to BufferOld - ldx BufferNew - stx BufferOld - ldx BufferNew+1 - stx BufferOld+1 - ldx BufferNew+2 - stx BufferOld+2 - // Handle Non Alphanumeric Keys - ldx NonAlphaFlagX - ldy NonAlphaFlagY - rts - -TooManyNewKeys: - sec - lda #$ff - sta BufferQuantity - sta SimultaneousAlphanumericKeysFlag - lda #$04 - rts - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -KeyTable: - .byte $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff // CRSR DOWN, F5, F3, F1, F7, CRSR RIGHT, RETURN, INST DEL - .byte $ff, $05, $13, $1a, $34, $01, $17, $33 // LEFT SHIFT, "E", "S", "Z", "4", "A", "W", "3" - .byte $18, $14, $06, $03, $36, $04, $12, $35 // "X", "T", "F", "C", "6", "D", "R", "5" - .byte $16, $15, $08, $02, $38, $07, $19, $37 // "V", "U", "H", "B", "8", "G", "Y", "7" - .byte $0e, $0f, $0b, $0d, $30, $0a, $09, $39 // "N", "O" (Oscar), "K", "M", "0" (Zero), "J", "I", "9" - .byte $2c, $00, $3a, $2e, $2d, $0c, $10, $2b // ",", "@", ":", ".", "-", "L", "P", "+" - .byte $2f, $1e, $3d, $ff, $ff, $3b, $2a, $1c // "/", "^", "=", RIGHT SHIFT, HOME, ";", "*", "£" - .byte $ff, $11, $ff, $20, $32, $ff, $1f, $31 // RUN STOP, "Q", "C=" (CMD), " " (SPC), "2", "CTRL", "<-", "1" - -BufferOld: - .byte $ff, $ff, $ff - -Buffer: - .byte $ff, $ff, $ff, $ff - -BufferQuantity: - .byte $ff - -SimultaneousAlphanumericKeysFlag: - .byte $00 -} \ No newline at end of file diff --git a/arch/precursor.asm b/arch/precursor.asm deleted file mode 100644 index 09f5b32..0000000 --- a/arch/precursor.asm +++ /dev/null @@ -1,801 +0,0 @@ -BasicUpstart2(start) - -// c64 -.const bgcolor = $d020 -.const bordercolor = $d021 -.const screenram = $0400 - -// kernel functions -.const kBsout = $ab1e //kernel character output sub -.const kChrout = $ffd2 -.const clearscreen = $e544 - -// chars -.const cr = 13 - -// memory map -.const kernel = $ff80 -.const start_basic = $0281 -.const end_basic = $0037 -.const step_size_garb = $000f -.const dataset = $0090 -.const input_dev = 153 -.const out_dev = 154 -.const time_1 = 160 -.const time_2 = 161 -.const time_3 = 162 -.const ds_motor = 192 - -// color petscii -.const color_cyan = $9f -.const color_light_blue = $9a -.const color_green = $1e - -// local const -.const pline_len = 40 -.const hex_open_chr = $5b -.const hex_close_chr = $5d - -// zero page -.const stringLow = $FB -.const stirngHigh = $FC - -.const videoLow = $FD -.const videoHigh = $FE - - -.macro printHexByte(stringAddr, value) { - lda #stringAddr - ldx value - jsr printhex_row -} - -.macro printHexWord(stringAddr, value) { - bPrint(stringAddr) - jsr popenhex - lda value+1 - jsr printhex - lda value - jsr printhex - jsr pclosehex - bChar(cr) -} - -.macro print(stringAddr) { - lda #stringAddr - jsr bsout -} - -.macro bPrint(stringAddr) { - lda #stringAddr - jsr bsout -} - -.macro bChar(char) { - lda #char - jsr kChrout -} - -//========================================================== -// code -//========================================================== - -start: - ldx #$00 // color - stx $d021 // set background color - stx $d020 // set border color - - lda #$04 - sta videoHigh - lda #$00 - sta videoLow - - jsr clearscreen - - bChar(color_cyan) - print(str_about) - - bChar(cr) - bChar(color_light_blue) - -getKeyb: - jsr Keyboard - bcs NoValidInput - stx TempX - sty TempY - cmp #$ff - // Check A for Alphanumeric keys - beq NoNewAphanumericKey - // jsr printhex - - cmp #'m' - beq mapMemory - cmp #'q' - beq exit - - jmp getKeyb - -NoNewAphanumericKey: - // Check X & Y for Non-Alphanumeric Keys - ldx TempX - ldy TempY - //stx $0401 - //sty $0402 -NoValidInput: // This may be substituted for an errorhandler if needed. - jmp getKeyb - -exit: rts - - -bsout: - sty stirngHigh - sta stringLow - - - ldy #$00 -bloop: lda (stringLow), y - cmp #0 - beq blexit - sta (videoLow), y - iny - cpy #$f0 - bne bcontinue - clc - lda videoLow - adc #$f0 - sta videoLow - lda videoHigh - adc #$00 - sta videoHigh -bcontinue: jmp bloop -blexit: - rts - - - - - -mapMemory: { - ldx #pline_len // lenht of pline - jsr pline - - // ---------------------- - // ------ map table start - // ---------------------- - - // kernel - printHexByte(str_row_kernel, kernel) - - // start basic area - printHexWord(str_row_basic_start, start_basic) - - // end basic area - printHexWord(str_row_basic_end, end_basic) - - // garbadge - printHexByte(str_row_step_size_garb, printhex_row) - - // dataset - printHexByte(str_row_dataset, dataset) - - // input dev - printHexByte(str_row_input_dev, input_dev) - - // out dev - printHexByte(str_row_out_dev, out_dev) - - // time 1 - printHexByte(str_row_time_1, time_1) - - // time 2 - printHexByte(str_row_time_2, time_2) - - // time 2 - printHexByte(str_row_time_2, time_3) - - // dataset motor - printHexByte(str_row_ds_motor, ds_motor) - - - // ---------------------- - // ------ map table end - // ---------------------- - bChar(cr) - - ldx #pline_len - jsr pline - rts -} - -// ———————————————————————————————————— -// popenhex -// ———————————————————————————————————— -popenhex: - bChar(hex_open_chr) - bChar(color_green) - rts - -// ———————————————————————————————————— -// pclosehex -// ———————————————————————————————————— -pclosehex: - bChar(color_light_blue) - bChar(hex_close_chr) - rts - -// ———————————————————————————————————— -// printhex_row -// ———————————————————————————————————— -// ———————————————————————————————————— -// preparatory ops: .a: msn ascii char -// .x: lsn ascii char -// .y: value -// -// returned values: none -// ———————————————————————————————————— -printhex_row: - sta a_cache // preserve a - txa // store x using a as it will be lost after ksout - pha - lda a_cache // get back a - jsr bsout - jsr popenhex - pla // saved x back in a from saved a - jsr printhex - jsr pclosehex - bChar(cr) - rts - -// ———————————————————————————————————— -// printhex -// ———————————————————————————————————— -// ———————————————————————————————————— -// preparatory ops: .a: byte to convert -// -// returned values: none -// ———————————————————————————————————— -printhex: - pha - jsr binhex - jsr kChrout - txa - jsr kChrout - pla - rts - -// ———————————————————————————————————— -// btohex -// ———————————————————————————————————— -// ———————————————————————————————————— -// preparatory ops: .a: byte to convert -// -// returned values: .a: msn ascii char -// .x: lsn ascii char -// .y: entry value -// ———————————————————————————————————— -binhex: pha //save byte - and #%00001111 //extract lsn - tax //save it - pla //recover byte - lsr //extract... - lsr //msn - lsr - lsr - pha //save msn - txa //lsn - jsr binhex1 //generate ascii lsn - tax //save - pla //get msn & fall thru -// -// convert nybble to hex ascii equivalent... -binhex1: cmp #$0a - bcc binhex2 //in decimal range - adc #$66 //hex compensate -binhex2: eor #%00110000 //finalize nybble - rts //done - - - -// ———————————————————————————————————— -// pline -// ———————————————————————————————————— -// ———————————————————————————————————— -// preparatory ops: .x: lenght -// returned values: none -// ———————————————————————————————————— -pline: - cpx #0 - bne pline_start - ldx #12 // default to 12 if 0 is passed in x -pline_start: lda #102 -pline_loop: jsr kChrout - dex - cpx #0 - bne pline_loop - lda #cr - jsr kChrout - rts - - -.encoding "screencode_mixed" -str_about: - .text "c=64 mapper v2.0 by =stid=" - .byte 0 -str_row_kernel: - .text " kernel " - .byte 0 -str_row_basic_start: - .text " start basic area " - .byte 0 -str_row_basic_end: - .text " end basic area " - .byte 0 -str_row_step_size_garb: - .text " step size garbage " - .byte 0 -str_row_dataset: - .text " dataset " - .byte 0 -str_row_input_dev: - .text " input device " - .byte 0 -str_row_out_dev: - .text " output device " - .byte 0 -str_row_time_1: - .text " time 1 " - .byte 0 -str_row_time_2: - .text " time 2 " - .byte 0 -str_row_time_3: - .text " time 3 " - .byte 0 -str_row_ds_motor: - .text " dataset motor " - .byte 0 -str_row_generic: - .text " hex value " - .byte 0 - - -a_cache: - .byte 0 - -TempX: - .byte 0 -TempY: - .byte 0 -cursorX: - .byte 0 -cursorY: - .byte 0 - - - -/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Keyboard IO Routine - ~~~~~~~~~~~~~~~~~~~ - By: TWW/CTR - - - Preparatory Settings - ~~~~~~~~~~~~~~~~~~~~ - None - - - Destroys - ~~~~~~~~ - Accumulator - X-Register - Y-Register - Carry / Zero / Negative - $dc00 - $dc01 - $50-$5f - - - Footprint - ~~~~~~~~~ - #$206 Bytes - - - Information - ~~~~~~~~~~~ - The routine uses "2 Key rollower" or up to 3 if the key-combination doesen't induce shadowing. - If 2 or 3 keys are pressed simultaneously (within 1 scan) a "No Activity" state has to occur before new valid keys are returned. - RESTORE is not detectable and must be handled by NMI IRQ. - SHIFT LOCK is not detected due to unreliability. - - - Usage - ~~~~~ - Example Code: - - jsr Keyboard - bcs NoValidInput - stx TempX - sty TempY - cmp #$ff - beq NoNewAphanumericKey - // Check A for Alphanumeric keys - sta $0400 - NoNewAphanumericKey: - // Check X & Y for Non-Alphanumeric Keys - ldx TempX - ldy TempY - stx $0401 - sty $0402 - NoValidInput: // This may be substituted for an errorhandler if needed. - - - Returned - ~~~~~~~~ - - +=================================================+ - | Returned in Accumulator | - +===========+===========+=============+===========+ - | $00 - @ | $10 - p | $20 - SPC | $30 - 0 | - | $01 - a | $11 - q | $21 - | $31 - 1 | - | $02 - b | $12 - r | $22 - | $32 - 2 | - | $03 - c | $13 - s | $23 - | $33 - 3 | - | $04 - d | $14 - t | $24 - | $34 - 4 | - | $05 - e | $15 - u | $25 - | $35 - 5 | - | $06 - f | $16 - v | $26 - | $36 - 6 | - | $07 - g | $17 - w | $27 - | $37 - 7 | - | $08 - h | $18 - x | $28 - | $38 - 8 | - | $09 - i | $19 - y | $29 - | $39 - 9 | - | $0a - j | $1a - z | $2a - * | $3a - : | - | $0b - k | $1b - | $2b - + | $3b - ; | - | $0c - l | $1c - £ | $2c - , | $3c - | - | $0d - m | $1d - | $2d - - | $3d - = | - | $0e - n | $1e - ^ | $2e - . | $3e - | - | $0f - o | $1f - <- | $2f - / | $3f - | - +-----------+-----------+-------------+-----------+ - - +================================================================================ - | Return in X-Register | - +=========+=========+=========+=========+=========+=========+=========+=========+ - | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | - +---------+---------+---------+---------+---------+---------+---------+---------+ - | CRSR UD | F5 | F3 | F1 | F7 | CRSR RL | RETURN |INST/DEL | - +---------+---------+---------+---------+---------+---------+---------+---------+ - - +================================================================================ - | Return in Y-Register | - +=========+=========+=========+=========+=========+=========+=========+=========+ - | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | - +---------+---------+---------+---------+---------+---------+---------+---------+ - |RUN STOP | L-SHIFT | C= | R-SHIFT |CLR/HOME | CTRL | | | - +---------+---------+---------+---------+---------+---------+---------+---------+ - - CARRY: - - Set = Error Condition (Check A for code): - A = #$01 => No keyboard activity is detected. - A = #$02 => Control Port #1 Activity is detected. - A = #$03 => Key Shadowing / Ghosting is detected. - A = #$04 => 2 or 3 new keys is detected within one scan - A = #$05 => Awaiting "No Activity" state - - Clear = Valid input - A = #$ff => No new Alphanumeric Keys detected (some key(s) being held down AND/OR some Non-Alphanumeric key is causing valid return). - A <> #$ff => New Alphanumeric Key returned. Non-Alphanumeric keys may also be returned in X or Y Register - - Issues/ToDo: - ~~~~~~~~~~~~ - - None - - - Improvements: - ~~~~~~~~~~~~~ - - Replace the subroutine with a pseudocommand and account for speedcode parameter (Memory vs. Cycles). - - Shorten the routine / Optimize if possible. - - - History: - ~~~~~~~~ - V2.5 - New test tool. - Added return of error codes. - Fixed a bug causing Buffer Overflow. - Fixed a bug in Non Alphanumerical Flags from 2.0. - V2.1 - Shortened the source by adding .for loops & Updated the header and some comments. - Added "simultaneous keypress" check. - V2.0 - Added return of non-Alphanumeric keys into X & Y-Registers. - Small optimizations here and there. - V1.1 - Unrolled code to make it faster and optimized other parts of it. - Removed SHIFT LOCK scanning. - V1.0 - First Working Version along with test tool. - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - - * = * "Keyboard Scan Routine" - - - // ZERO PAGE Varibles - .const ScanResult = $50 // 8 bytes - .const BufferNew = $58 // 3 bytes - .const KeyQuantity = $5b // 1 byte - .const NonAlphaFlagX = $5c // 1 byte - .const NonAlphaFlagY = $5d // 1 byte - .const TempZP = $5e // 1 byte - .const SimultaneousKeys = $5f // 1 byte - - // Operational Variables - .var MaxKeyRollover = 3 - -Keyboard: -{ - jmp Main - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Routine for Scanning a Matrix Row - -KeyInRow: - asl - bcs *+5 - jsr KeyFound - .for (var i = 0 ; i < 7 ; i++) { - inx - asl - bcs *+5 - jsr KeyFound - } - rts - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Routine for handling: Key Found - -KeyFound: - stx TempZP - dec KeyQuantity - bmi OverFlow - ldy KeyTable,x - ldx KeyQuantity - sty BufferNew,x - ldx TempZP - rts - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Routine for handling: Overflow - -OverFlow: - pla // Dirty hack to handle 2 layers of JSR - pla - pla - pla - // Don't manipulate last legal buffer as the routine will fix itself once it gets valid input again. - lda #$03 - sec - rts - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Exit Routine for: No Activity - -NoActivityDetected: - // Exit With A = #$01, Carry Set & Reset BufferOld. - lda #$00 - sta SimultaneousAlphanumericKeysFlag // Clear the too many keys flag once a "no activity" state is detected. - stx BufferOld - stx BufferOld+1 - stx BufferOld+2 - sec - lda #$01 - rts - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Exit Routine for Control Port Activity - -ControlPort: - // Exit with A = #$02, Carry Set. Keep BufferOld to verify input after Control Port activity ceases - sec - lda #$02 - rts - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Configure Data Direction Registers -Main: - ldx #$ff - stx $dc02 // Port A - Output - ldy #$00 - sty $dc03 // Port B - Input - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Check for Port Activity - - sty $dc00 // Connect all Keyboard Rows - cpx $dc01 - beq NoActivityDetected - - lda SimultaneousAlphanumericKeysFlag - beq !+ - // Waiting for all keys to be released before accepting new input. - lda #$05 - sec - rts -!: - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Check for Control Port #1 Activity - - stx $dc00 // Disconnect all Keyboard Rows - cpx $dc01 // Only Control Port activity will be detected - bne ControlPort - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Scan Keyboard Matrix - - lda #%11111110 - sta $dc00 - ldy $dc01 - sty ScanResult+7 - sec - .for (var i = 6 ; i > -1 ; i--) { - rol - sta $dc00 - ldy $dc01 - sty ScanResult+i - } - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Check for Control Port #1 Activity (again) - - stx $dc00 // Disconnect all Keyboard Rows - cpx $dc01 // Only Control Port activity will be detected - bne ControlPort - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Initialize Buffer, Flags and Max Keys - - // Reset current read buffer - stx BufferNew - stx BufferNew+1 - stx BufferNew+2 - - // Reset Non-AlphaNumeric Flag - inx - stx NonAlphaFlagY - - // Set max keys allowed before ignoring result - lda #MaxKeyRollover - sta KeyQuantity - - // Counter to check for simultaneous alphanumeric key-presses - lda #$fe - sta SimultaneousKeys - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Check and flag Non Alphanumeric Keys - - lda ScanResult+6 - eor #$ff - and #%10000000 // Left Shift - lsr - sta NonAlphaFlagY - lda ScanResult+0 - eor #$ff - and #%10100100 // RUN STOP - C= - CTRL - ora NonAlphaFlagY - sta NonAlphaFlagY - lda ScanResult+1 - eor #$ff - and #%00011000 // Right SHIFT - CLR HOME - ora NonAlphaFlagY - sta NonAlphaFlagY - - lda ScanResult+7 // The rest - eor #$ff - sta NonAlphaFlagX - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Check for pressed key(s) - - lda ScanResult+7 - cmp #$ff - beq *+5 - jsr KeyInRow - .for (var i = 6 ; i > -1 ; i--) { - ldx #[7-i]*8 - lda ScanResult+i - beq *+5 - jsr KeyInRow - } - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Key Scan Completed - - // Put any new key (not in old scan) into buffer - ldx #MaxKeyRollover-1 - !: lda BufferNew,x - cmp #$ff - beq Exist // Handle 'null' values - cmp BufferOld - beq Exist - cmp BufferOld+1 - beq Exist - cmp BufferOld+2 - beq Exist - // New Key Detected - inc BufferQuantity - ldy BufferQuantity - sta Buffer,y - // Keep track of how many new Alphanumeric keys are detected - inc SimultaneousKeys - beq TooManyNewKeys - Exist: - dex - bpl !- - - // Anything in Buffer? - ldy BufferQuantity - bmi BufferEmpty - // Yes: Then return it and tidy up the buffer - dec BufferQuantity - lda Buffer - ldx Buffer+1 - stx Buffer - ldx Buffer+2 - stx Buffer+1 - jmp Return - -BufferEmpty: // No new Alphanumeric keys to handle. - lda #$ff - -Return: // A is preset - clc - // Copy BufferNew to BufferOld - ldx BufferNew - stx BufferOld - ldx BufferNew+1 - stx BufferOld+1 - ldx BufferNew+2 - stx BufferOld+2 - // Handle Non Alphanumeric Keys - ldx NonAlphaFlagX - ldy NonAlphaFlagY - rts - -TooManyNewKeys: - sec - lda #$ff - sta BufferQuantity - sta SimultaneousAlphanumericKeysFlag - lda #$04 - rts - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -KeyTable: - .byte $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff // CRSR DOWN, F5, F3, F1, F7, CRSR RIGHT, RETURN, INST DEL - .byte $ff, $05, $13, $1a, $34, $01, $17, $33 // LEFT SHIFT, "E", "S", "Z", "4", "A", "W", "3" - .byte $18, $14, $06, $03, $36, $04, $12, $35 // "X", "T", "F", "C", "6", "D", "R", "5" - .byte $16, $15, $08, $02, $38, $07, $19, $37 // "V", "U", "H", "B", "8", "G", "Y", "7" - .byte $0e, $0f, $0b, $0d, $30, $0a, $09, $39 // "N", "O" (Oscar), "K", "M", "0" (Zero), "J", "I", "9" - .byte $2c, $00, $3a, $2e, $2d, $0c, $10, $2b // ",", "@", ":", ".", "-", "L", "P", "+" - .byte $2f, $1e, $3d, $ff, $ff, $3b, $2a, $1c // "/", "^", "=", RIGHT SHIFT, HOME, ";", "*", "£" - .byte $ff, $11, $ff, $20, $32, $ff, $1f, $31 // RUN STOP, "Q", "C=" (CMD), " " (SPC), "2", "CTRL", "<-", "1" - -BufferOld: - .byte $ff, $ff, $ff - -Buffer: - .byte $ff, $ff, $ff, $ff - -BufferQuantity: - .byte $ff - -SimultaneousAlphanumericKeysFlag: - .byte $00 -} \ No newline at end of file diff --git a/main.asm b/main.asm index 2af392e..5eed83d 100644 --- a/main.asm +++ b/main.asm @@ -1,4 +1,4 @@ -//BasicUpstart2(start) +// BasicUpstart2(start) #import "mem_map.asm" * = $8000 "Main" @@ -6,9 +6,18 @@ //------------------------------------------------------------------------------------ .const MAIN_COLOR = $03 .const BORDER_COLOR = $05 -.const SCREEN_MEM = $0400 .const CR = $0d .const BS = $14 +.const ADV_CHAR = '@' +.const INIT_IRQ = $fda3 +.const INIT_MEM = $fd50 +.const INIT_IO = $fd15 +.const INIT_VID = $ff5b +.const SCRN_CTRL = $d016 +.const RASTER_LINE = $d012 +.const INTERRUPT_CTRL = $dc0d +.const NMSK_INTERRUPT_CTRL = $dd0d +.const TIMER_A_CTRL = $DC0E //------------------------------------------------------------------------------------ .word coldstart // coldstart vector @@ -30,43 +39,50 @@ coldstart: sei txs cld - stx $d016 - jsr $fda3 // Prepare IRQ - jsr $fd50 // Init memory. Rewrite this routine to speed up boot process. - jsr $fd15 // Init I/O - jsr $ff5b // Init video + stx SCRN_CTRL // Set Screen Bits + jsr INIT_IRQ // Prepare IRQ + jsr INIT_MEM // Init memory. Rewrite this routine to speed up boot process. + jsr INIT_IO // Init I/O + jsr INIT_VID // Init video cli + +* = * "App Start" + //------------------------------------------------------------------------------------ start: - //sei - jsr initApp; + print(lineString) print(testString) + print(lineString) + loop: lda #$FF -Raster: cmp $D012 +Raster: cmp RASTER_LINE // Raster done? bne Raster jsr Keyboard2.ReadKeyb jsr Keyboard2.GetKey bcs loop + + cmp #CR - beq cr + beq execute cmp #BS beq backspace inputChar: - jsr Shell.push + jsr Shell.push // Char in Buffer cPrint() jmp loop backspace: jsr Shell.backspace cPrint() jmp loop -cr: - jsr Shell.push + +execute: + jsr Shell.push // CR in Buffer jsr Screen.screenNewLine - jsr Shell.wozExec + jsr Shell.exec jsr Screen.screenNewLine jsr Shell.clear jmp loop @@ -76,21 +92,21 @@ initApp: { sei lda #$7f - sta $dc0d // disable timer interrupts which can be generated by the two CIA chips - sta $dd0d // the kernal uses such an interrupt to flash the cursor and scan the keyboard, so we better - // stop it. + sta INTERRUPT_CTRL // disable timer interrupts which can be generated by the two CIA chips + sta NMSK_INTERRUPT_CTRL // the kernal uses such an interrupt to flash the cursor and scan the keyboard, so we better + // stop it. - lda $dc0d // by reading this two registers we negate any pending CIA irqs. - lda $dd0d // if we don't do this, a pending CIA irq might occur after we finish setting up our irq. - // we don't want that to happen. + lda INTERRUPT_CTRL // by reading this two registers we negate any pending CIA irqs. + lda NMSK_INTERRUPT_CTRL // if we don't do this, a pending CIA irq might occur after we finish setting up our irq. + // we don't want that to happen. // Disable 0e TIMER lda #254 - and $dc0e - sta $dc0e + and TIMER_A_CTRL + sta TIMER_A_CTRL ClearColorRam($00) - ClearScreen(SCREEN_MEM, ' ') + ClearScreen(' ') SetBorderColor(BORDER_COLOR) SetBackgroundColor(MAIN_COLOR) jsr Screen.init @@ -118,7 +134,8 @@ minor: .byte 05 testString: .text "woz64 mon - v 0.1.5" - .byte $8e + .byte $8e, 0 +lineString: .text "----------------------------------------" .byte $8e, 0 hoaxString: diff --git a/memory.asm b/memory.asm index 8f6fab9..f6ae82c 100644 --- a/memory.asm +++ b/memory.asm @@ -3,22 +3,22 @@ * = * "Memory Routines" .macro clone(from, to, dest) { - lda #from - sta MemMap.MEMORY.from+1 + lda #from + sta MemMap.MEMORY.from+1 - lda #dest - sta MemMap.MEMORY.dest+1 + lda #dest + sta MemMap.MEMORY.dest+1 - lda #to-from - sta MemMap.MEMORY.size + lda #to-from + sta MemMap.MEMORY.size - jsr Memory._clone + jsr Memory._clone } .filenamespace Memory diff --git a/screen.asm b/screen.asm index 12a300e..713deef 100644 --- a/screen.asm +++ b/screen.asm @@ -2,6 +2,8 @@ #import "math.asm" #import "memory.asm" + + // ----------------------- // MACROS // ----------------------- @@ -9,83 +11,80 @@ * = * "Screen Routines" .macro print(stringAddr) { - lda #stringAddr // High byte - jsr Screen.print + lda #stringAddr // High byte + jsr Screen.print } .macro cPrint() { - jsr Screen.printPetChar + jsr Screen.printPetChar } -.macro ClearScreen(screen, clearByte) { - lda #clearByte - ldx #0 -!loop: - sta screen, x - sta screen + $100, x - sta screen + $200, x - sta screen + $300, x - inx - bne.r !loop- +.macro ClearChunks(baseAddress, clearByte) { + lda #clearByte + ldx #0 + !loop: + sta baseAddress, x + sta baseAddress + $100, x + sta baseAddress + $200, x + sta baseAddress + $300, x + inx + bne.r !loop- +} + + +.macro ClearScreen(clearByte) { + ClearChunks(Screen.VIDEO_ADDR, clearByte) } .macro ClearColorRam(clearByte) { - lda #clearByte - ldx #0 -!loop: - sta $D800, x - sta $D800 + $100, x - sta $D800 + $200, x - sta $D800 + $300, x - inx - bne.r !loop- + ClearChunks(Screen.COLOR_ADDR, clearByte) } .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() { - lda $d016 - ora #16 - sta $d016 + lda $d016 + ora #16 + sta $d016 } .macro SetScrollMode() { - lda $D016 - eor #%00001000 - sta $D016 + lda $D016 + eor #%00001000 + sta $D016 } .filenamespace Screen -// ----------------------- +//------------------------------------------------------------------------------------ // CONSTANTS -// ----------------------- - -.const VIDEO_ADDR = $0400 -.const COLUMN_NUM = 40 -.const ROWS_NUM = 25 -.const CR = $8e -.const BS = $95 +//------------------------------------------------------------------------------------ +.label VIDEO_ADDR = $0400 +.label COLOR_ADDR = $D800 +.label COLUMN_NUM = 40 +.label ROWS_NUM = 25 +.label CR = $8e +.label BS = $95 @@ -104,12 +103,12 @@ scrollUp: { clone(VIDEO_ADDR+40, VIDEO_ADDR+(COLUMN_NUM*(ROWS_NUM)), VIDEO_ADDR) // clear last line - lda #32 - ldx #40 + lda #32 + ldx #40 !: sta VIDEO_ADDR+(COLUMN_NUM*(ROWS_NUM-1)), x dex - bne !- + bpl !- // x == -1 dec MemMap.SCREEN.CursorRow pla rts @@ -130,6 +129,7 @@ printPetChar: { //------------------------------------------------------------------------------------ printChar: { + sei stx MemMap.SCREEN.tempX cmp #CR bne.r !+ @@ -194,11 +194,11 @@ noEndOfLine: pla // This is a backspace - cmp #BS - bne !+ - lda #' ' + cmp #BS + bne !+ + lda #' ' sta (MemMap.SCREEN.TempVideoPointer), y - jmp exit + jmp exit !: // insert into screen @@ -209,6 +209,7 @@ noEndOfLine: exit: ldx MemMap.SCREEN.tempX + cli rts } @@ -223,17 +224,17 @@ noEndOfLine: // returned values: none // —————————————————————————————————————————————————————— print: { - 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 - exit: - rts + 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 + exit: + rts } diff --git a/shell.asm b/shell.asm index 98dbcf9..6d2ee88 100644 --- a/shell.asm +++ b/shell.asm @@ -37,6 +37,41 @@ backspace: { rts } +exec: { + lda MemMap.SHELL.buffer // Check first char + cmp #'!' + beq stidExec // if ! is stid mon command + jmp wozExec // Otherwise exec Woz + // Expect exec functions to RTS +} + + +stidExec: { + .break + ldy #1 + + lda MemMap.SHELL.buffer, y + + cmp #'h' + beq cmdHelp + + cmp #'r' + beq cmdReset + +done: + rts + +cmdHelp: + print(helpString) + jmp done + +cmdReset: + jmp $fce2 // SYS 64738 + + +} + + // WOZ MONITOR FLOW - FROM APPLE1 wozExec: { @@ -194,4 +229,20 @@ PRHEX: and #%00001111 // Mask LSD for hex prin } +//------------------------------------------------------------------------------------ +* = * "Shell Data" + +.encoding "screencode_mixed" + +helpString: + .text "----------------------" + .byte $8e + .text "h : this help" + .byte $8e + .text "r : hard reset" + .byte $8e + .text "z : zero page params" + .byte $8e, 0 + + #import "mem_map.asm"