Created
December 10, 2012 03:39
-
-
Save travisby/4248251 to your computer and use it in GitHub Desktop.
Mapped Display with Interrupts Example For CUSP Assemby
This file contains 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
.EQU @,$000 ;Initialize Program Counter | |
.EQU KBDCTRL,$000 ;Keyboard Control Port | |
.EQU KBDSTS,$000 ; Keyboard Status Port, same thing | |
.EQU KBDATA,$001 ;Keyboard Data Port | |
.EQU VDBUF,$101 ;Video Buffer's First Address (it's really the second, but it printed too close) | |
.EQU VDCTRL,$316 ;Video Control Port | |
.EQU VDDATA,$317 ;Video Data Port | |
.EQU HEIGHT,14 ;The height of CUSP's Screen | |
.EQU WIDTH,38 ;The Width of CUSP's Screen | |
.EQU LEN,5 ;The length I wanted each line to be | |
LDS $E00 ;Initialize Stack | |
LDX# 0 ;Load 0 into the XR, so we can use it for our mapped display. So we do video buffer + XR to get a point on the screen | |
SIE ;Enable the use of Interrupts in our application | |
LOOP: ;We return here every time a character is entered. | |
LDA# 255 ;This is "1111111" in binary. To tell the keyboard to "enable interrupt" and "clear buffer after use", we had to give it "11XXXXXX". The way I did this was by giving the largest binary value we could. Anything >=192 would have worked | |
OUTB KBDCTRL ;Send our message to the Keyboard Control. We want it to throw an interrupt when it has input, and clear the buffer afterwards | |
LDA# 0 ;This is part of the trickery for our interrupt wait routine. It's basically like polling. | |
STA ISDONE ;We save 0 into ISDONE, so we can continuously check it. | |
WAIT: ;You will see the interrupt ISR actually sets ISDONE to 1, so we break out of the loop then. | |
LDA ISDONE | |
CMA# 0 | |
JEQ WAIT | |
;So, assume "ISR" has run by now. See that next. When the keyboard gets data, it calls ISR, no matter where in WAIT it is. | |
LDA KBVALUE ;Get our value from the keyboard that we saved in ISR | |
OUTB+ VDBUF ;Print it out to (video buffer + XR) | |
ADX# 1 ;Add 1 to the XR, so we move to the next character on our string | |
INC COUNT ;Increment count, to keep track of how many characters we have printed | |
LDA COUNT | |
MOD# LEN ;Compare COUNT to LEN. If it's divisible, go to a new line | |
CMA# 0 | |
JEQ NEWLINE | |
JMP LOOP ;LET'S DO IT AGAIN!!!! | |
NEWLINE: ;This is some trickery for the mapped screen display | |
ADX# WIDTH-LEN ;We subtract LEN from the WIDTH, and add that to our current XR. This moves Y down a full position minus the length | |
JMP LOOP | |
HLT | |
ISDONE:.WORD 0 ;Used to track whether or not we have exited the Interrupt Service Routine | |
KBVALUE:.WORD 0 ;Stores the value we get from the keyboard | |
ISR: | |
LDA# 1 | |
STA ISDONE ;Store 1 to break out of "WAIT" loop | |
INB KBDATA ;Get in from the keyboard | |
STA KBVALUE ;Save it | |
IRTN ;Super secret special return statement | |
.EQU @,$FF8 ;This is tricky. When a keyboard interrupt is thrown, it's going to call whatever program is in location FF8. So we put OUR program in FF8! | |
.WORD ISR ;That program is, "ISR". So now "ISR" is in $FF8. So when a KB interrupt is thrown, ISR is called. | |
COUNT: .WORD 0 ;Yeah... this is in the totes wrong place. But it works. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There are a few improvements that could come to this program.