Skip to content

Commit a647c7c

Browse files
committed
Add emulator graphic mode, add test snake game. Commit from aitplane
1 parent c6fd694 commit a647c7c

9 files changed

Lines changed: 283 additions & 59 deletions

File tree

emulator/js/DrunkPC.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const IO_KBD_ADDR = 0b00100000 // A5 = 1 - device 1
1818
const COMPACT_FLASH_BASE = 0b01000000 // A6 = 1 - device 2
1919

2020
let ram = new Uint8Array(0xFFFF + 1);
21-
let romLocked = false;
21+
let romLocked = true;
2222
let video = new RA6963();
2323
let keyboard = new Keyboard();
2424
let cf = new CompactFlash();

emulator/js/RA6963.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,13 +244,12 @@ function RA6963() {
244244
}
245245
if (graphicMode) {
246246
for (let canvasY = 0; canvasY < canvas.height; canvasY++) {
247-
for (let canvasX = 0; canvasX < (canvas.width / 8); canvasX++) {
248-
const dataByte = vram[graphicHomeAddressPtr + (canvasY * DISPLAY_WIDTH / 8) + canvasX];
249-
for(let bit = 7; bit >= 0; bit--) {
247+
for (let canvasX = 0; canvasX < (canvas.width / 6); canvasX++) {
248+
const dataByte = vram[graphicHomeAddressPtr + (canvasY * DISPLAY_WIDTH / 6) + canvasX];
249+
for(let bit = 5; bit >= 0; bit--) {
250250
if ((dataByte >> bit) & 0x01) {
251-
canvasSetPixelState((canvasX * 8) + (8 - bit), canvasY);
251+
canvasSetPixelState((canvasX * 6) + (6 - bit), canvasY);
252252
} else {
253-
canvasSetPixelState(canvasX + (8 - bit), canvasY, false);
254253
}
255254

256255
}

software/applications/snake/snake.s

Lines changed: 149 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66

77
.include "drivers/ra6963/ra6963.inc"
88
.include "hardware/io.inc"
9+
.include "keyboard/keyboard_codes.inc"
910

1011
.section .text
1112

1213
; snake direction
1314
DIRECTION_UP = 0
14-
DIRECTION_DOWN = 1
15-
DIRECTION_LEFT = 2
16-
DIRECTION_RIGHT = 3
15+
DIRECTION_RIGHT = 1
16+
DIRECTION_DOWN = 2
17+
DIRECTION_LEFT = 3
1718

1819
; constants
1920
MAX_SNAKE_LEN = 253
@@ -26,21 +27,120 @@ snake_await_tick_process_keyboard:
2627
pop hl ; return char code
2728
ld a, l ; loading byte
2829
or a ; if it zero?
29-
jr z, snake_await_tick_process_keyboard_await_keyboard
30+
jr z, timer_move_snake
3031
; check 'q'
3132
cp 'q' ; if q pressed
3233
jr z, snake_await_tick_process_keyboard_end
3334
cp 'Q' ; if Q pressed
3435
jr z, snake_await_tick_process_keyboard_end
35-
;cp KBD_UP ; if up pressed
36-
;jr z, less_process_file_keyboard_up
37-
;cp KBD_DOWN ; if down pressed
38-
;jr z, less_process_file_keyboard_down
36+
cp KBD_UP ; if up pressed
37+
jr z, snake_up
38+
cp KBD_DOWN ; if down pressed
39+
jr z, snake_down
40+
cp KBD_LEFT ; if left pressed
41+
jr z, snake_left
42+
cp KBD_RIGHT ; if right pressed
43+
jr z, snake_right
44+
jr timer_move_snake
45+
46+
snake_up:
47+
ld a, DIRECTION_UP
48+
ld (snake_direction), a
49+
jr no_key
50+
snake_down:
51+
ld a, DIRECTION_DOWN
52+
ld (snake_direction), a
53+
jr no_key
54+
snake_left:
55+
ld a, DIRECTION_LEFT
56+
ld (snake_direction), a
57+
jr no_key
58+
snake_right:
59+
ld a, DIRECTION_RIGHT
60+
ld (snake_direction), a
61+
jr no_key
62+
63+
timer_move_snake:
64+
call clear_display
65+
call move_snake
66+
call draw_snake
67+
68+
no_key:
3969
jr snake_await_tick_process_keyboard_await_keyboard ; keyboard loop
4070
snake_await_tick_process_keyboard_end:
4171
ret
4272

73+
move_snake:
74+
call snake_set_next_step
75+
call snake_step
76+
ret
77+
78+
snake_step:
79+
push hl ; storing hl
80+
push de ; storing de
81+
82+
ld hl, (snake_len) ; loading snake len
83+
add hl, hl ; sizeof(snakePoint) = x and y = snake_len * 2
84+
push hl ; arg3 of memmove - size
85+
ld hl, snake_dots
86+
push hl ; arg2 of memmove - src arr
87+
ld hl, snake_dots + 2
88+
push hl ; arg1 of memmove - dst arr
89+
call memmove
90+
91+
ld hl, snake_next_step ; snake_next_step need to be set by snake_set_next_step function
92+
ld e, (hl) ; dereferencing next step
93+
inc hl
94+
ld d, (hl) ; dereferencing next step
95+
ld (snake_dots), de ; setting moved snake_dots head with the new dot
96+
97+
pop de ; restoring de
98+
pop hl ; restoring hl
99+
ret
100+
101+
snake_set_next_step:
102+
push af ; storing af
103+
push hl ; storing hl
104+
105+
ld hl, (snake_dots) ; loading current last point, h - y, l - x
106+
107+
ld a, (snake_direction) ; loading snake direction
108+
cp DIRECTION_UP
109+
jr z, snake_set_next_step_direction_up
110+
cp DIRECTION_RIGHT
111+
jr z, snake_set_next_step_direction_right
112+
cp DIRECTION_DOWN
113+
jr z, snake_set_next_step_direction_down
114+
cp DIRECTION_LEFT
115+
jr z, snake_set_next_step_direction_left
116+
jr snake_set_next_step_end_do_nothing ; if not any match
117+
118+
snake_set_next_step_direction_up:
119+
dec h ; y--
120+
jr snake_set_next_step_end
121+
122+
snake_set_next_step_direction_down:
123+
inc h ; y++
124+
jr snake_set_next_step_end
125+
126+
snake_set_next_step_direction_right:
127+
inc l ; x++
128+
jr snake_set_next_step_end
129+
130+
snake_set_next_step_direction_left:
131+
dec l ; x--
132+
jr snake_set_next_step_end
133+
134+
snake_set_next_step_end:
135+
ld (snake_next_step), hl ; storing next step
136+
snake_set_next_step_end_do_nothing:
137+
138+
pop hl ; restoring hl
139+
pop af ; restoring af
140+
ret
141+
43142
draw_snake:
143+
push af
44144
push hl
45145
push de
46146
push bc
@@ -49,43 +149,69 @@ draw_snake:
49149
ld b, a
50150
ld hl, snake_dots
51151
draw_snake_loop:
152+
ld de, 0x0404 ; arg2 of ra6963_draw_box - size_x, size_y
153+
push de
154+
52155
ld e, (hl) ; x
53156
inc hl ; going yo y
54157
ld d, (hl) ; y
158+
159+
; multiplying x by 4(snake size)
160+
push bc ; storing bc
161+
ld b, 3 ; snake size
162+
ld a, e ; loading x
163+
draw_snake_loop_multiply_by_4_loop_x:
164+
add a, e
165+
djnz draw_snake_loop_multiply_by_4_loop_x
166+
ld e, a ; multiplyed value
167+
168+
; multiplying y by 4(snake size)
169+
ld b, 3 ; snake size
170+
ld a, d ; loading y
171+
draw_snake_loop_multiply_by_4_loop_y:
172+
add a, d
173+
djnz draw_snake_loop_multiply_by_4_loop_y
174+
ld d, a ; multiplyed value
175+
pop bc ; restoring bc
176+
55177
push de ; arg1 of ra6963_set_pixel
56-
call ra6963_set_pixel
178+
179+
call ra6963_draw_box
180+
57181
inc hl ; next snake point
58182
djnz draw_snake_loop
59183
draw_snake_loop_end:
60184
pop bc
61185
pop de
62186
pop hl
187+
pop af
63188
ret
64189

65190
clear_display:
66191
push hl ; storing hl
67192
ld hl, 0 ; arg3 for ra6963_memset - value
68193
push hl
69-
ld hl, 1920 ; arg2 for ra6963_memset - size
194+
ld hl, 2560 ; arg2 for ra6963_memset - size (240/6 * 64)
70195
push hl
71196
ld hl, 0 ; arg1 for ra6963_memset - address
72197
push hl
73198
call ra6963_memset
74199
pop hl ; restoring hl
200+
ret
75201

76202
init_snake:
77-
push hl
78-
push de
79-
push bc
203+
push hl ; storing hl
204+
push de ; storing de
205+
push bc ; storing bc
80206

81-
ld de, snake_dots
82-
ld hl, snake_dots_init
83-
ld bc, INITIAL_SNAKE_LEN * 2
207+
ld de, snake_dots ; dst arr
208+
ld hl, snake_dots_init ; src arr
209+
ld bc, INITIAL_SNAKE_LEN * 2 ; arr size
84210
ldir ; repeats 'ld (de), (hl)' then increments de, hl, and decrements bc until bc=0
85211

86-
pop bc
87-
pop de
88-
pop hl
212+
pop bc ; restoring bc
213+
pop de ; restoring de
214+
pop hl ; restoring hl
89215
ret
90216

91217
write_byte:
@@ -100,34 +226,7 @@ snake_main:
100226
call ra6963_graphic_on
101227
call clear_display
102228

103-
ld hl, 0x0000
104-
push hl
105-
call ra6963_set_address_pointer
106-
107-
ld a, 0x3F
108-
call write_byte
109-
ld a, 0
110-
call write_byte
111-
ld a, 0xF0
112-
call write_byte
113-
ld a, 0x0F
114-
call write_byte
115-
116-
;ld hl, 0x00EF
117-
;push hl
118-
;call ra6963_set_pixel
119-
120-
;ld hl, 0x3FEF
121-
;push hl
122-
;call ra6963_set_pixel
123-
124-
;ld hl, 0x3F00
125-
;push hl
126-
;call ra6963_set_pixel
127-
128-
;call init_snake
129-
130-
;call draw_snake
229+
call init_snake
131230

132231
call snake_await_tick_process_keyboard
133232

@@ -138,6 +237,9 @@ snake_main:
138237
snake_dots:
139238
.skip (2 * MAX_SNAKE_LEN)
140239

240+
snake_next_step:
241+
.skip 2
242+
141243
.section .data
142244
snake_direction:
143245
.byte DIRECTION_RIGHT
@@ -158,4 +260,3 @@ snake_dots_init:
158260
.byte 3, 6
159261
.byte 2, 6
160262

161-
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
.include "string/string.inc"
2+
3+
.section .text
4+
5+
; About:
6+
; The memmove() function copies byte array arr1 to byte array arr2.
7+
; Both arrays are assumed to be n bytes long.
8+
; Args:
9+
; uint8_t* arr1 - first array ptr
10+
; uint8_t* arr2 - second array ptr
11+
; uint16_t size - arrays size
12+
; Return:
13+
; uint8_t res - 0 if both arrays are equal
14+
; C Prototype:
15+
; uint8_t memmove(uint8_t* arr1, uint8_t* arr2, uint16_t size);
16+
memmove:
17+
push af ; storing af
18+
push ix ; storing ix
19+
push hl ; storing hl
20+
push de ; storing de
21+
push bc ; storing bc
22+
23+
ld ix, 12 ; there is no way to set load sp value to ix, skipping pushed 5 reg pairs and the return address
24+
add ix, sp ; loading sp value to ix
25+
26+
ld l, (ix + 2) ; arr2 ptr low byte
27+
ld h, (ix + 3) ; arr3 ptr high byte
28+
ld c, (ix + 4) ; arrs size low byte
29+
ld b, (ix + 5) ; arrs size high byte
30+
ld de, memmove_buffer
31+
32+
ldir ; repeats 'ld (de), (hl)' then increments de, hl, and decrements bc until bc=0
33+
34+
ld e, (ix + 0) ; arr1 ptr low byte
35+
ld d, (ix + 1) ; arr1 ptr high byte
36+
ld c, (ix + 4) ; arrs size low byte
37+
ld b, (ix + 5) ; arrs size high byte
38+
ld hl, memmove_buffer
39+
40+
ldir ; repeats 'ld (de), (hl)' then increments de, hl, and decrements bc until bc=0
41+
42+
pop bc ; restoring bc
43+
pop de ; restoring de
44+
pop hl ; restoring hl
45+
pop ix ; restoring ix
46+
pop af ; restoring af
47+
48+
exx ; exchanging register pairs with their shadow
49+
pop hl ; return address
50+
pop bc ; removing arg1
51+
pop bc ; removing arg2
52+
pop bc ; removing arg3
53+
push hl ; return address
54+
exx ; restoring registers
55+
56+
ret
57+
58+
59+
.section .bss
60+
; temp workaround before malloc function will exists..
61+
memmove_buffer:
62+
.skip 256

software/lib/stdlib/string/string.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
.global memrchr
1313
.global memswap
1414
.global memcmp
15+
.global memmove
1516

1617
; vim: set ft=asm:

software/system/drivers/ra6963/ra6963.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ RA6963_OFFSET_REGISTER_VALUE = RA6963_CUSTOM_FONT_START_ADDR / 2048
7676
.global ra6963_custom_font_init
7777
.global ra6963_memcpy
7878
.global ra6963_text_mode_cursor_off
79+
.global ra6963_draw_box
7980
.global ra6963_text_mode_cursor_on
8081

8182
.global ra6963_graphic_on

0 commit comments

Comments
 (0)