Skip to content

Commit

Permalink
Add some nifty shit to stdio.s.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
haldean committed Feb 13, 2014
1 parent 853f592 commit 5a3c040
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 16 deletions.
26 changes: 19 additions & 7 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,13 @@ Extensions to the 6502 instruction set

I/O memory map:

There are three I/O devices right now: a character input
device, a character output device and a virtual
terminal. Convenience constants and macros for the
character I/O devices are defined in `stdlib/stdio.s'
for use in user programs. Add stdlib to your include
path and then add `#include <stdio.s>' to your program
to use these constants.
There are four I/O devices right now: a character input
device, a character output device, a virtual terminal
and a block device. Convenience constants and macros for
the character I/O devices are defined in
`stdlib/stdio.s' for use in user programs. Add stdlib to
your include path and then add `#include <stdio.s>' to
your program to use these constants.

I/O options are controlled by setting bits on the I/O
flag byte at address 0xFF02. The current set of
Expand Down Expand Up @@ -141,6 +141,18 @@ I/O devices:
sample_programs/echo.s, and an example of a vterm
application is provided in sample_programs/spam.s

A block device can be mapped in with control addresses
at 0xFF03 through 0xFF07. To use the block device, you
must specify a binary disk image to back the device
using the -d flag. To read from the block device, write
an address in the disk image to 0xFF03 and 0xFF04, with
the low byte in 0xFF03. The value at that location in
the disk image will be written to 0xFF05, which your
program can then read. To write, set the memory address
to write to using the same method, then write the
desired byte to 0xFF06. If any of these operations
return an error, the byte at 0xFF07 will be nonzero.

Reading the source

x6502 was written to be easy to understand and read. A
Expand Down
2 changes: 1 addition & 1 deletion main.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ int main(int argc, char *argv[]) {
return -1;
}

debugf("using %s as a backing file for block device 0\n", blck0_file);
if (blck0_file != NULL) {
debugf("using %s as a backing file for block device 0\n", blck0_file);
FILE *blck0 = fopen(blck0_file, "r+");
if (blck0 == NULL) {
fprintf(stderr, "block file %s does not exist.\n", blck0_file);
Expand Down
4 changes: 3 additions & 1 deletion sample_programs/README
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Test 6502 assembler programs. Generate binaries with:

xa -w -bt 0x0100 -Istdlib/ sample_programs/test.s
xa -w -Istdlib/ sample_programs/test.s

xa is a cross-assembler and utility suite for 65xx series processors. It's
included in many package repositories as `xa65', including Homebrew on OSX in
Expand All @@ -20,3 +20,5 @@ Sample programs:
spam.s Writes A through Z repeatedly, filling the vterm.
Demonstrates vterm output and how to do indirect
addressing to address the whole vterm.
stdlib_test.s Demo program displaying the functionality of the
standard library.
5 changes: 4 additions & 1 deletion sample_programs/diskread/gendisk.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ int main() {
printf("could not open file, err: %s", strerror(errno));
return 1;
}
fprintf(f, "hello, world!");
fprintf(f, "hello, world, from disk!\n");
fputc(0, f);
fseek(f, 0xFF00, SEEK_SET);
fprintf(f, "hello from a seeked position.\n");
fclose(f);
return 0;
}
Binary file modified sample_programs/diskread/testdisk.bin
Binary file not shown.
26 changes: 26 additions & 0 deletions sample_programs/stdlib_test.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include <stdio.s>

lda #$02 ; set WAIT_TERMINATE flag
sta iomode
lda #<str
sta $F0
lda #>str
sta $F1
jsr print

lda #$00
sta blck0_addrl
sta blck0_addrh
jsr fread
jsr print

lda #$00
sta blck0_addrl
lda #$FF
sta blck0_addrh
jsr fread
jsr print

ext

str: .asc "hello, world, from .data!", $0A, $00
82 changes: 76 additions & 6 deletions stdlib/stdio.s
Original file line number Diff line number Diff line change
@@ -1,11 +1,81 @@
; defines useful constants for writing 6502 assembler that targets x6502

putc = $FF00
getc = $FF01
iomode = $FF02
paint = $FEE8
; defines useful constants and methods for writing 6502 assembler that targets x6502

#define debug .byt $FC
#define ext .byt $FF
#define DEBUG debug
#define EXT ext

.(
jmp prog

+putc = $FF00
+getc = $FF01
+iomode = $FF02
+paint = $FEE8

+blck0_addrl = $FF03
+blck0_addrh = $FF04
+blck0_read = $FF05
+blck0_write = $FF06
+blck0_err = $FF07

; print reads two bytes from $00F0, treats them as a memory address, then
; reads from that memory address and prints those characters to the character
; device until a NUL character is found. the printed string must be less than
; 256 characters long.
+print:
.(
pha
ldy #$00
loop:
lda ($F0),Y
cmp #$00
beq done
sta putc
iny
; check that y hasn't overflowed
cpy #$00
beq done
jmp loop
done:
pla
rts
.)

; fread reads up to 255 bytes into a memory region that starts at the address in
; $00F0 from the current position of the block device until a null character is
; encountered.
+fread:
.(
pha
ldy #$00

loop:
lda blck0_read
; TODO check read status

sta ($F0),Y

iny
; check that y hasn't overflowed
cpy #$00
beq done

; increment disk address, using carry addition
clc
lda #$01
adc blck0_addrl
sta blck0_addrl
lda #$00
adc blck0_addrh
sta blck0_addrh

jmp loop

done:
pla
rts
.)

prog:
.)

0 comments on commit 5a3c040

Please sign in to comment.