mirror of
https://github.com/specht/champ.git
synced 2025-01-13 09:34:06 +00:00
documentation
This commit is contained in:
parent
1cec19787c
commit
7f0529db03
23
README.md
23
README.md
@ -192,6 +192,29 @@ To disable a watch, add a `;` right behind the `@`:
|
||||
ADC FOO ; @;Au(post)
|
||||
```
|
||||
|
||||
### Error reporting
|
||||
|
||||
Should your program run into an error, champ shows you where in the source code the error occured and an execution log of the previous 20 CPU steps (you can increase the size of the log with `--error-log-size`).
|
||||
Look at this example ([example05.yaml](example05.yaml) / [example05.s](example05.s)):
|
||||
|
||||
```
|
||||
DSK test
|
||||
MX %11
|
||||
ORG $6000
|
||||
|
||||
LDX #$ff
|
||||
COUNT PHA
|
||||
PHA
|
||||
DEX
|
||||
BNE COUNT
|
||||
```
|
||||
|
||||
This is a program which repeatedly pushes the A register onto the stack until the stack is full. Stack overflow, mission accomplished! Champ will generate the following output:
|
||||
|
||||
![Error report](doc/example05_1.gif?raw=true)
|
||||
|
||||
On the left hand side you can see that the error occured in example05.s, line 7, while attempting a `PHA` operation when `SP` is already down to zero from previous `PHA` operations (as can be seen on the right).
|
||||
|
||||
## Did you know?
|
||||
|
||||
By the way, there's a full-fledged, incremental, standalone, no-dependencies GIF encoder in [pgif.c](pgif.c) that writes animated GIFs and uses some optimizations to further minimize space. It's stream-friendly and as you feed pixels in via `stdin`, it dutifully writes GIF data to `stdout` until `stdin` gets closed.
|
||||
|
2
champ.rb
2
champ.rb
@ -853,7 +853,7 @@ class Champ
|
||||
def parse_merlin_output(path)
|
||||
input_file = File.basename(@source_path)
|
||||
@source_for_file[input_file] = File.read(@source_path).split("\n").map { |x| x.gsub("\t", ' ' * 4) }
|
||||
@max_source_width_for_file[input_file] = @source_for_file[input_file].map { |x| x.size }.max
|
||||
@max_source_width_for_file[input_file] = [@source_for_file[input_file].map { |x| x.size }.max, 40].max
|
||||
|
||||
@source_line = -3
|
||||
File.open(path, 'r') do |f|
|
||||
|
BIN
doc/example05_1.gif
Normal file
BIN
doc/example05_1.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
@ -2,16 +2,8 @@
|
||||
MX %11
|
||||
ORG $6000
|
||||
|
||||
LDX #$20
|
||||
JSR COUNT
|
||||
LDX #$30
|
||||
JSR COUNT
|
||||
LDX #$40
|
||||
JSR COUNT
|
||||
|
||||
BRK
|
||||
|
||||
COUNT DEX ; @Xu(post) @cycles
|
||||
LDX #$ff
|
||||
COUNT PHA
|
||||
PHA
|
||||
DEX
|
||||
BNE COUNT
|
||||
BRK
|
||||
RTS
|
||||
|
20
p65c02.c
20
p65c02.c
@ -31,6 +31,7 @@ uint64_t frame_count = 0;
|
||||
|
||||
uint16_t start_pc = 0x6000;
|
||||
uint16_t start_frame_pc = 0xffff;
|
||||
uint16_t old_pc = 0;
|
||||
|
||||
uint16_t yoffset[192] = {
|
||||
0x0000, 0x0400, 0x0800, 0x0c00, 0x1000, 0x1400, 0x1800, 0x1c00,
|
||||
@ -98,6 +99,7 @@ typedef struct {
|
||||
} r_watch;
|
||||
|
||||
r_watch *watches = 0;
|
||||
uint8_t watches_allocated = 0;
|
||||
size_t watch_count = 0;
|
||||
int32_t watch_offset_for_pc_and_post[0x20000];
|
||||
|
||||
@ -150,6 +152,9 @@ void push(uint8_t value)
|
||||
{
|
||||
if (cpu.sp == 0)
|
||||
{
|
||||
printf("error %04x Stack overflow\n", old_pc);
|
||||
fflush(stdout);
|
||||
|
||||
fprintf(stderr, "Stack overflow!\n");
|
||||
exit(1);
|
||||
}
|
||||
@ -161,6 +166,8 @@ uint8_t pop()
|
||||
{
|
||||
if (cpu.sp == 0xff)
|
||||
{
|
||||
printf("error %04x Stack underrun\n", old_pc);
|
||||
fflush(stdout);
|
||||
fprintf(stderr, "Stack underrun!\n");
|
||||
exit(1);
|
||||
}
|
||||
@ -564,7 +571,7 @@ void branch(uint8_t condition, int8_t offset, uint8_t* cycles)
|
||||
|
||||
void handle_next_opcode()
|
||||
{
|
||||
uint16_t old_pc = cpu.pc;
|
||||
old_pc = cpu.pc;
|
||||
|
||||
// fetch opcode, addressing mode and cycles for next instruction
|
||||
uint8_t read_opcode = 0;
|
||||
@ -575,6 +582,9 @@ void handle_next_opcode()
|
||||
|
||||
if (opcode == NO_OPCODE || addressing_mode == NO_ADDRESSING_MODE)
|
||||
{
|
||||
printf("error %04x Unhandled opcode: %02x\n", old_pc, read_opcode);
|
||||
fflush(stdout);
|
||||
|
||||
fprintf(stderr, "Unhandled opcode at %04x: %02x\n", old_pc, read_opcode);
|
||||
exit(1);
|
||||
}
|
||||
@ -1067,10 +1077,14 @@ int main(int argc, char** argv)
|
||||
int watch_index = 0;
|
||||
while (fgets(s, 1024, stdin))
|
||||
{
|
||||
if (!watches)
|
||||
if (s[0] == '\n')
|
||||
break;
|
||||
if (!watches_allocated)
|
||||
{
|
||||
watch_count = parse_int(s, 0);
|
||||
watches = malloc(sizeof(r_watch) * watch_count);
|
||||
if (watch_count > 0)
|
||||
watches = malloc(sizeof(r_watch) * watch_count);
|
||||
watches_allocated = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user