git.haldean.org x6502 / 5a3c040
Add some nifty shit to stdio.s. Adds print and fread functions, both of which read NUL-terminated strings. print writes them using the character output device, and fread reads them from the block device to a region of memory. Will Haldean Brown 7 years ago
7 changed file(s) with 129 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
6565
6666 I/O memory map:
6767
68 There are three I/O devices right now: a character input
69 device, a character output device and a virtual
70 terminal. Convenience constants and macros for the
71 character I/O devices are defined in `stdlib/stdio.s'
72 for use in user programs. Add stdlib to your include
73 path and then add `#include <stdio.s>' to your program
74 to use these constants.
68 There are four I/O devices right now: a character input
69 device, a character output device, a virtual terminal
70 and a block device. Convenience constants and macros for
71 the character I/O devices are defined in
72 `stdlib/stdio.s' for use in user programs. Add stdlib to
73 your include path and then add `#include <stdio.s>' to
74 your program to use these constants.
7575
7676 I/O options are controlled by setting bits on the I/O
7777 flag byte at address 0xFF02. The current set of
139139 capabilities of x6502 is provided in
140140 sample_programs/echo.s, and an example of a vterm
141141 application is provided in sample_programs/spam.s
142
143 A block device can be mapped in with control addresses
144 at 0xFF03 through 0xFF07. To use the block device, you
145 must specify a binary disk image to back the device
146 using the -d flag. To read from the block device, write
147 an address in the disk image to 0xFF03 and 0xFF04, with
148 the low byte in 0xFF03. The value at that location in
149 the disk image will be written to 0xFF05, which your
150 program can then read. To write, set the memory address
151 to write to using the same method, then write the
152 desired byte to 0xFF06. If any of these operations
153 return an error, the byte at 0xFF07 will be nonzero.
142154
143155 Reading the source
144156
5151 return -1;
5252 }
5353
54 debugf("using %s as a backing file for block device 0\n", blck0_file);
5554 if (blck0_file != NULL) {
55 debugf("using %s as a backing file for block device 0\n", blck0_file);
5656 FILE *blck0 = fopen(blck0_file, "r+");
5757 if (blck0 == NULL) {
5858 fprintf(stderr, "block file %s does not exist.\n", blck0_file);
00 Test 6502 assembler programs. Generate binaries with:
11
2 xa -w -bt 0x0100 -Istdlib/ sample_programs/test.s
2 xa -w -Istdlib/ sample_programs/test.s
33
44 xa is a cross-assembler and utility suite for 65xx series processors. It's
55 included in many package repositories as `xa65', including Homebrew on OSX in
1919 spam.s Writes A through Z repeatedly, filling the vterm.
2020 Demonstrates vterm output and how to do indirect
2121 addressing to address the whole vterm.
22 stdlib_test.s Demo program displaying the functionality of the
23 standard library.
77 printf("could not open file, err: %s", strerror(errno));
88 return 1;
99 }
10 fprintf(f, "hello, world!");
10 fprintf(f, "hello, world, from disk!\n");
11 fputc(0, f);
12 fseek(f, 0xFF00, SEEK_SET);
13 fprintf(f, "hello from a seeked position.\n");
1114 fclose(f);
1215 return 0;
1316 }
0 #include <stdio.s>
1
2 lda #$02 ; set WAIT_TERMINATE flag
3 sta iomode
4 lda #<str
5 sta $F0
6 lda #>str
7 sta $F1
8 jsr print
9
10 lda #$00
11 sta blck0_addrl
12 sta blck0_addrh
13 jsr fread
14 jsr print
15
16 lda #$00
17 sta blck0_addrl
18 lda #$FF
19 sta blck0_addrh
20 jsr fread
21 jsr print
22
23 ext
24
25 str: .asc "hello, world, from .data!", $0A, $00
0 ; defines useful constants for writing 6502 assembler that targets x6502
1
2 putc = $FF00
3 getc = $FF01
4 iomode = $FF02
5 paint = $FEE8
0 ; defines useful constants and methods for writing 6502 assembler that targets x6502
61
72 #define debug .byt $FC
83 #define ext .byt $FF
94 #define DEBUG debug
105 #define EXT ext
6
7 .(
8 jmp prog
9
10 +putc = $FF00
11 +getc = $FF01
12 +iomode = $FF02
13 +paint = $FEE8
14
15 +blck0_addrl = $FF03
16 +blck0_addrh = $FF04
17 +blck0_read = $FF05
18 +blck0_write = $FF06
19 +blck0_err = $FF07
20
21 ; print reads two bytes from $00F0, treats them as a memory address, then
22 ; reads from that memory address and prints those characters to the character
23 ; device until a NUL character is found. the printed string must be less than
24 ; 256 characters long.
25 +print:
26 .(
27 pha
28 ldy #$00
29 loop:
30 lda ($F0),Y
31 cmp #$00
32 beq done
33 sta putc
34 iny
35 ; check that y hasn't overflowed
36 cpy #$00
37 beq done
38 jmp loop
39 done:
40 pla
41 rts
42 .)
43
44 ; fread reads up to 255 bytes into a memory region that starts at the address in
45 ; $00F0 from the current position of the block device until a null character is
46 ; encountered.
47 +fread:
48 .(
49 pha
50 ldy #$00
51
52 loop:
53 lda blck0_read
54 ; TODO check read status
55
56 sta ($F0),Y
57
58 iny
59 ; check that y hasn't overflowed
60 cpy #$00
61 beq done
62
63 ; increment disk address, using carry addition
64 clc
65 lda #$01
66 adc blck0_addrl
67 sta blck0_addrl
68 lda #$00
69 adc blck0_addrh
70 sta blck0_addrh
71
72 jmp loop
73
74 done:
75 pla
76 rts
77 .)
78
79 prog:
80 .)