Option 1: Adding Calculator[edit]
- Create a subroutine which enables the user to enter two numbers of up to two digits. Indicate where the cursor is, and allow the user to use the digit keys (0-9), backspace, and enter keys. Return the user's input value in the accumulator (A) register.
- Using this subroutine, write a program which add the two numbers (each of which is in the range 0-99) and print the result.
- Optional challenge: extend to more than 2 digits and add a running total capability with a clear key.
Option 2: Data Input Form[edit]
- Create a subroutine which enables the user to enter a string of up to 40 characters. Decide how the data will be returned from the subroutine. The user should be able to use the left/right cursor keys and backspace to edit the text, and the cursor location should be visible to the user.
- Write a program which uses this subroutine to collect the user's name, address, city, province, and postal code, and then display this information formatted as a shipping address (for example, as shown below).
Your order will be delivered to: J. Doe 1750 Finch Ave E Toronto ON M2J 2X5
- Optional challenge: validate the province/territory and the postal code format.
Option 3: Hexdump[edit]
- Create a subroutine which enables the user to enter a 4-digit hexadecimal value. Allow the use of the backspace key for editing, and show the user the cursor location. Decide how the data will be returned by this subroutine.
- Using this subroutine, ask the user for a starting address and a length (in bytes), and then output a hexdump of the specified memory locations, formatted to show address and data information in some layout. If the output is longer than the screen, pause for user input (e.g., "Press ENTER to continue" or something similar) every 20 lines.
- Optional challenge: add a display of ASCII data on the right-hand side, similar to the output of the linux command
od -A x -t xz -v filename
Option 4: Screen Colour Selector[edit]
- Create a subroutine which displays on the character display a list of colours available on the bitmapped display, one colour per line, with one of the colours names highlighted in reverse video (white on black). The user may use the up/down arrow keys to change the highlighted row. Return the user's selection as a number in the accumulator (A) register when they press Enter.
- Using this subroutine, get a colour from the user, then fill the bitmap display with this colour, and allow the user to select a different colour.
- Optional challenge: update the colour on the bitmapped display as the user scrolls through the colour-selector list.
So out of these options our group decided to go for options 2 and 4 which were data input form and screen colour selector. We decided to work on the screen color selector first.
Now as we were working on the lab the professor gave us 2 commands that would be useful for the lab which were pha and pla which stand for PUSH Accumulator and PULL accumulator respectively. Pha simply copies whatever is in the accumulator and stores it on the stack while Pha doing the opposite takes 1 byte from the stack and stores it in the accumulator.
Now we started by displaying the names of the colors by declaring them as constant bytes and then printing them on character display but soon we figured out the old way of displaying things by starting displaying from the character display's start address would not prove very useful and we would have to use ROM routines in order to work on this lab. Now ROM routines are pre defined subroutines in the memory that we can access and use for basic functionalities. Here is a list of them:
; ROM routines define SCINIT $ff81 ; initialize/clear screen define CHRIN $ffcf ; input character from keyboard define CHROUT $ffd2 ; output character to screen define SCREEN $ffed ; get screen size define PLOT $fff0 ; get/set cursor coordinates
Well, after getting to display the names, the next task was to get the cursor moving up and down that list and displaying the color based on the position of cursor. While we had limited time in lab we could only manage to go so far and decided to complete the lab afterwards.
Lecture:
Well this week's lecture introduced us to 2 architectures which were fairly new to us though we use them a lot, x86 64 and AArch 64. We were given a background on both those architectures and how those 2 emerged from being small in memory chips to being so huge memory and powerful now.
Then we got to know the registers on both the architectures. While AArch 64 had 0-30 registers and a register 31 that could be used as zero register or stack pointer based on its functionality. More on these registers and some related instruction set can be found on:
While on the other hand X86 64 had 16 registers, more of which could be found on:
It was interesting to know how both the architectures had registers that could be used for 64 bit or 32 bit wide access.
Now going back to the lab, we took from the code from the previous lab on how to scroll using input from the keyboard and we went further to store the color, address cur_pos held inside and we manipulated the cursor to store different color's code according to the input from the keyboard, as they ranged from 0-F. So after managing to change the color code based on keyboard up or down key and making it print the stored code using the filling the bitmapped display's code we were able to come up with the following code:
; ROM routines
define SCINIT $ff81 ; initialize/clear screen
define CHRIN $ffcf ; input character from keyboard
define CHROUT $ffd2 ; output character to screen
define SCREEN $ffed ; get screen size
define PLOT $fff0 ; get/set cursor coordinates
define cur_pos $10
jsr SCINIT
ldy #$00
ldx #$00
stx cur_pos
char: lda color_list,y
beq main
jsr CHROUT
iny
bne char
main:
lda $ff ; get a keystroke
beq main ; fix freezing on max speed
ldx #$00 ; clear out the key buffer
stx $ff
cmp #$82 ; arrow down for increment (going down)
beq incr
cmp #$80 ; arrow up for decrement (going up)
beq decr
jmp main ; if no key pressed loop forever
clear_cursor:
lda #$2d ; character -
jsr print_cursor
rts
incr:
jsr clear_cursor
inc cur_pos
lda cur_pos
cmp #$10
beq incr_reset
bne incr_decr
incr_reset:
lda #$00
sta cur_pos
jmp incr_decr
decr:
jsr clear_cursor
dec cur_pos
lda cur_pos
cmp #$FF
beq decr_reset
bne incr_decr
decr_reset:
lda #$0F
sta cur_pos
jmp incr_decr
incr_decr:
lda #$93 ; character black box
jsr print_cursor
jmp paint
print_cursor:
clc ; select the SET function for PLOT
ldx #$00
ldy cur_pos ; increment this one
pha ; save the value of A into the stack
jsr PLOT ; set the cursor position
pla ; restore the value of A from the stack
jsr CHROUT ; print the char
rts
paint:
ldx #$06 ; max value for $11
ldy #$00 ; index
lda #$00 ; set pointer at $10 to $0200
sta $11
lda #$02
sta $12
lda cur_pos ; set the color
jmp paint_loop
paint_loop:
sta ($11),y ; store colour
iny ; increment index
bne paint_loop ; branch until page done
inc $12 ; increment high byte of pointer
cpx $12 ; compare with max value
bne paint_loop ; continue if not done
jmp main ; done - return to main
color_list:
dcb $93,"B","l","a","c","k",13
dcb "-","W","h","i","t","e",13
dcb "-","R","e","d",13
dcb "-","C","y","a","n",13
dcb "-","P","u","r","p","l","e",13
dcb "-","G","r","e","e","n",13
dcb "-","B","l","u","e",13
dcb "-","Y","e","l","l","o","w",13
dcb "-","O","r","a","n","g","e",13
dcb "-","B","r","o","w","n",13
dcb "-","L","i","g","h","t",32,"r","e","d",13
dcb "-","D","a","r","k",32,"g","r","e","y",13
dcb "-","G","r","e","y",13
dcb "-","L","i","g","h","t",32,"g","r","e","e","n",13
dcb "-","L","i","g","h","t",32,"b","l","u","e",13
dcb "-","L","i","g","h","t",32,"g","r","e","y",00
As you can see we used ROM routines CHROUT and PLOT to print the characters to the display and setting the position of the cursor in the memory respectively.
Though we managed to pull of this first task we still had one more to go.
No comments:
Post a Comment