Created
January 3, 2016 06:38
-
-
Save BleuLlama/2428ed6683360b082c0f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ca65 V2.15 - Git b6f429f | |
Main file : llamacalc.asm | |
Current file: llamacalc.asm | |
000000r 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
000000r 1 ; LlamaCalc - a programmer's calculator for KIM (1/Uno) | |
000000r 1 ; | |
000000r 1 ; 2016-01 Scott Lawrence | |
000000r 1 ; | |
000000r 1 ; Created for the RetroChallenge RC2016-1 | |
000000r 1 ; Scott Lawrence - [email protected] | |
000000r 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
000000r 1 | |
000000r 1 .define VERSIONH #$00 | |
000000r 1 .define VERSIONL #$01 | |
000000r 1 ; v 0001 - 2016-01-01 - initial version, keypad input support | |
000000r 1 | |
000000r 1 | |
000000r 1 ; define the functionality we want to use in the library | |
000000r 1 UseVideoDisplay0 = 1 ; video display 0 | |
000000r 1 | |
000000r 1 ; include our functions | |
000000r 1 .include "KimDefs.asm" | |
000000r 2 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; | |
000000r 2 ; Kim OS defines | |
000000r 2 | |
000000r 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
000000r 2 ; keypad | |
000000r 2 | |
000000r 2 ; key presses | |
000000r 2 AK = $1EFE ; ROMFN: key down a=0, key up a<>0 | |
000000r 2 GETKEY = $1F6A ; ROMFN: A>15 = bad key, otherwise, it's the key | |
000000r 2 | |
000000r 2 ; key codes | |
000000r 2 .define KEY_NONE #$15 | |
000000r 2 .define KEY_SPECIAL_MASK #$10 | |
000000r 2 .define KEY_AD #$10 | |
000000r 2 .define KEY_DA #$11 | |
000000r 2 .define KEY_PC #$14 | |
000000r 2 .define KEY_PL #$12 | |
000000r 2 | |
000000r 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
000000r 2 ; 7-seg display | |
000000r 2 | |
000000r 2 SCANDS = $1F1F ; F9, FA, FB -> Display | |
000000r 2 POINTH = $FB | |
000000r 2 POINTL = $FA | |
000000r 2 INH = $F9 | |
000000r 2 | |
000000r 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
000000r 2 ; Serial TTY | |
000000r 2 | |
000000r 2 GETCH = $1E5A ; ROMFN: Gets TTY char to A | |
000000r 2 OUTCH = $1EA0 ; ROMFN: Prints A as ASCII to TTY | |
000000r 2 OUTSP = $1E9E ; ROMFN: Prints ' ' to TTY | |
000000r 2 PRTBYT = $1E3B ; ROMFN: TTY Out A as 2 hex chars | |
000000r 2 PRTPNT = $1E1D ; ROMFN: Prints FB, FA to TTY | |
000000r 2 | |
000000r 2 | |
000000r 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
000000r 2 ; Video Display 0 | |
000000r 2 | |
000000r 2 RASTER = $4000 ; base of raster memory | |
000000r 2 | |
000000r 2 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; | |
000000r 2 | |
000000r 1 .include "KimLib.asm" | |
000000r 2 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; | |
000000r 2 ; KimLib | |
000000r 2 ; Standard use library functions | |
000000r 2 ; | |
000000r 2 ; 2015-12-29+ | |
000000r 2 ; Scott Lawrence - [email protected] | |
000000r 2 | |
000000r 2 ; include this after including "KimDefines.asm" | |
000000r 2 ; your code should start with the label "main" | |
000000r 2 | |
000000r 2 ; defineables: | |
000000r 2 ; UseVideoDisplay0 - turn on Video Display framebuffer at $4000 | |
000000r 2 | |
000000r 2 | |
000000r 2 ; for standard, we'll start at 0100. | |
000000r 2 .org $0100 | |
000100 2 | |
000100 2 | |
000100 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
000100 2 ; entrypoint | |
000100 2 ; - this is where the code will start from | |
000100 2 ; - we have this jump to the user's 'main' | |
000100 2 entrypoint: | |
000100 2 4C 40 01 jmp main | |
000103 2 | |
000103 2 | |
000103 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
000103 2 ; end | |
000103 2 ; - jump here to end everything | |
000103 2 end: | |
000103 2 00 brk | |
000104 2 | |
000104 2 .if .defined(UseVideoDisplay0) | |
000104 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
000104 2 ; cls | |
000104 2 ; - clear the screen | |
000104 2 ; - jsr cls - fills with black | |
000104 2 ; - jsr fillscr - fills with the color in (A & 0x0F) | |
000104 2 cls: | |
000104 2 A9 00 lda #$00 ; a = 7 ; color | |
000106 2 | |
000106 2 fillscr: | |
000106 2 AA tax ; x = a (store it aside) | |
000107 2 A0 FF ldy #$FF ; y = 0 | |
000109 2 | |
000109 2 clsloop: | |
000109 2 C8 iny ; y++ | |
00010A 2 8A txa ; restore color | |
00010B 2 | |
00010B 2 ; we'll do this call 4 times for each 255 byte (0x0100) sections | |
00010B 2 ; we could do it once for each section, but it's a lot slower. | |
00010B 2 ; we can do it 8 times for each section, but it doubles the code | |
00010B 2 ; chunk, so we'll just go with this for now. whatever. | |
00010B 2 99 00 40 sta RASTER + $0000, y | |
00010E 2 99 40 40 sta RASTER + $0040, y | |
000111 2 99 80 40 sta RASTER + $0080, y | |
000114 2 99 C0 40 sta RASTER + $00C0, y | |
000117 2 | |
000117 2 99 00 41 sta RASTER + $0100, y | |
00011A 2 99 40 41 sta RASTER + $0140, y | |
00011D 2 99 80 41 sta RASTER + $0180, y | |
000120 2 99 C0 41 sta RASTER + $01C0, y | |
000123 2 | |
000123 2 99 00 42 sta RASTER + $0200, y | |
000126 2 99 40 42 sta RASTER + $0240, y | |
000129 2 99 80 42 sta RASTER + $0280, y | |
00012C 2 99 C0 42 sta RASTER + $02C0, y | |
00012F 2 | |
00012F 2 99 00 43 sta RASTER + $0300, y | |
000132 2 99 40 43 sta RASTER + $0340, y | |
000135 2 99 80 43 sta RASTER + $0380, y | |
000138 2 99 C0 43 sta RASTER + $03C0, y | |
00013B 2 | |
00013B 2 ; use $FF for single, $7F for double, $3F for quad | |
00013B 2 C0 3F cpy #$3F ; does y==(last)? | |
00013D 2 D0 CA bne clsloop ; nope, go again | |
00013F 2 | |
00013F 2 60 rts | |
000140 2 | |
000140 2 .endif ; UseVideoDisplay0 | |
000140 2 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; | |
000140 2 | |
000140 1 | |
000140 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
000140 1 ;; RAM used | |
000140 1 KEYBAK = $10 | |
000140 1 SHIFTSCRATCH = $11 | |
000140 1 | |
000140 1 | |
000140 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
000140 1 ; main | |
000140 1 ; - the library entry point. | |
000140 1 main: | |
000140 1 .if .defined(UseVideoDisplay0) | |
000140 1 20 04 01 jsr cls ; clear the screen black | |
000143 1 .endif | |
000143 1 20 4F 01 jsr cls7seg | |
000146 1 20 5B 01 jsr displayVersion ; display the version number | |
000149 1 4C 6B 01 jmp keyinput ; press a key, get a color | |
00014C 1 20 03 01 jsr end ; end it | |
00014F 1 | |
00014F 1 | |
00014F 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
00014F 1 cls7seg: | |
00014F 1 ; 1. clear the 7 segment display | |
00014F 1 A9 00 lda #$00 | |
000151 1 85 FB sta POINTH ; left two digits | |
000153 1 85 FA sta POINTL ; middle two digits | |
000155 1 85 F9 sta INH ; right two digits | |
000157 1 20 1F 1F jsr SCANDS ; draw it to the display | |
00015A 1 60 rts | |
00015B 1 | |
00015B 1 displayVersion: | |
00015B 1 A9 00 lda #$00 | |
00015D 1 85 F9 sta INH ; right two digits | |
00015F 1 | |
00015F 1 A9 00 lda VERSIONH | |
000161 1 85 FB sta POINTH ; v00 | |
000163 1 A9 01 lda VERSIONL | |
000165 1 85 FA sta POINTL ; 01 | |
000167 1 | |
000167 1 20 1F 1F jsr SCANDS ; draw it to the display | |
00016A 1 60 rts | |
00016B 1 | |
00016B 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
00016B 1 keyinput: | |
00016B 1 ; check for key | |
00016B 1 20 6A 1F jsr GETKEY ; get a keypress | |
00016E 1 C9 15 cmp KEY_NONE ; $15 is "no press" | |
000170 1 F0 F9 beq keyinput ; then there's no press, check again | |
000172 1 | |
000172 1 ; store aside a backup of the press | |
000172 1 85 10 sta KEYBAK ; KeyBak = a | |
000174 1 | |
000174 1 ; check for AD/DA/PC/+ keys | |
000174 1 29 10 and KEY_SPECIAL_MASK | |
000176 1 C9 10 cmp KEY_SPECIAL_MASK | |
000178 1 D0 10 bne keyShiftIntoDisplay ; nope. regular key press | |
00017A 1 | |
00017A 1 ; it's a control key! | |
00017A 1 handleControlKey: | |
00017A 1 A5 10 lda KEYBAK ; restore A | |
00017C 1 85 F9 sta INH ; just shove it to the display | |
00017E 1 A9 00 lda #$0 ; clear A | |
000180 1 85 FA sta POINTL ; short circuit | |
000182 1 85 FB sta POINTH | |
000184 1 20 1F 1F jsr SCANDS ; update display | |
000187 1 4C 6B 01 jmp keyinput ; repeat | |
00018A 1 | |
00018A 1 | |
00018A 1 ; handler for nibbles... | |
00018A 1 keyShiftIntoDisplay: | |
00018A 1 ; right byte | |
00018A 1 A5 10 lda KEYBAK ; A = Key pressed (A to be shifted in) | |
00018C 1 | |
00018C 1 A6 F9 ldx INH ; X = INH | |
00018E 1 20 AC 01 jsr shifter ; shift around nibbles | |
000191 1 86 F9 stx INH ; store X back out | |
000193 1 | |
000193 1 ; middle byte | |
000193 1 A6 FA ldx POINTL ; X from the byte | |
000195 1 20 AC 01 jsr shifter ; shift ecverything around | |
000198 1 86 FA stx POINTL ; store the modified X back out | |
00019A 1 | |
00019A 1 ; left byte | |
00019A 1 A6 FB ldx POINTH ; X from the byte | |
00019C 1 20 AC 01 jsr shifter ; shift ecverything around | |
00019F 1 86 FB stx POINTH ; store the modified X back out | |
0001A1 1 | |
0001A1 1 ; and finally display it to the screen | |
0001A1 1 20 1F 1F jsr SCANDS ; and display it to the screen | |
0001A4 1 | |
0001A4 1 | |
0001A4 1 .if .defined(UseVideoDisplay0) | |
0001A4 1 ; and display the color | |
0001A4 1 A5 10 lda KEYBAK | |
0001A6 1 20 06 01 jsr fillscr ; fill the screen | |
0001A9 1 .endif | |
0001A9 1 | |
0001A9 1 4C 6B 01 jmp keyinput ; repeat... | |
0001AC 1 | |
0001AC 1 | |
0001AC 1 ; shifter | |
0001AC 1 ; roll A through X (for keypad->multibyte display use) | |
0001AC 1 ; eg: A=$0D X=$4C -> X=$CD A=$0C | |
0001AC 1 ; in: A - nibble to shift in from the right | |
0001AC 1 ; in: X - byte to work on | |
0001AC 1 ; mod: Y - scratch | |
0001AC 1 ; out: A - nibble shifted out | |
0001AC 1 shifter: | |
0001AC 1 ; 1. store aside A in Y | |
0001AC 1 29 0F and #$0F ; clean up A (just in case) | |
0001AE 1 85 11 sta SHIFTSCRATCH | |
0001B0 1 ; A = input byte / nib | |
0001B0 1 ; X = starting byte | |
0001B0 1 ; SHIFTSCRATCH = masked input nibble | |
0001B0 1 | |
0001B0 1 ; 2. generate carry result, store on stack | |
0001B0 1 8A txa ; A = X | |
0001B1 1 4A lsr | |
0001B2 1 4A lsr | |
0001B3 1 4A lsr | |
0001B4 1 4A lsr ; A >>= 4 (shift nibble down) | |
0001B5 1 ;and #$0F ; A &= 0x0F (mask it) (unnecessary due to LSR) | |
0001B5 1 48 pha ; push A onto stack | |
0001B6 1 | |
0001B6 1 ; A = carry nibble (junk now) | |
0001B6 1 ; X = starting byte | |
0001B6 1 ; SHIFTSCRATCH = masked input nibble | |
0001B6 1 ; stack = x >> 4 (carry nibble) | |
0001B6 1 | |
0001B6 1 ; 3. shift nibble and apply new carry in | |
0001B6 1 8A txa ; A = X | |
0001B7 1 0A asl | |
0001B8 1 0A asl | |
0001B9 1 0A asl | |
0001BA 1 0A asl ; a <<=4 (shift nibble up) | |
0001BB 1 ;and #$F0 ; A &= 0xF0 (mask it) (unnecessary due to ASL) | |
0001BB 1 05 11 ora SHIFTSCRATCH ; A = A | SCRATCH ( shift in nibble) | |
0001BD 1 ; A = output byte (shifted nibbles) | |
0001BD 1 ; X = junk | |
0001BD 1 ; SHIFTSCRATCH = masked input nibble (junk now) | |
0001BD 1 | |
0001BD 1 ; 4. Setup return values | |
0001BD 1 AA tax ; X = A | |
0001BE 1 68 pla ; pop A from stack (from 2.) | |
0001BF 1 ; X = output byte | |
0001BF 1 ; A = carry nibble | |
0001BF 1 | |
0001BF 1 ; 5. and return | |
0001BF 1 60 rts ; return | |
0001BF 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment