1
0
mirror of https://github.com/cc65/cc65.git synced 2025-01-21 15:32:41 +00:00

Added testcode for new function to switch working screen

This commit is contained in:
mc78 2024-08-26 23:16:31 +02:00
parent c4ba32a1c2
commit bbf5e88c65
3 changed files with 224 additions and 0 deletions

57
targettest/c64/Makefile Normal file
View File

@ -0,0 +1,57 @@
# Run 'make SYS=<target>'; or, set a SYS env.
# var. to build for another target system.
SYS ?= c64
# Just the usual way to find out if we're
# using cmd.exe to execute make rules.
ifneq ($(shell echo),)
CMD_EXE = 1
endif
ifdef CMD_EXE
NULLDEV = nul:
DEL = -del /f
RMDIR = rmdir /s /q
else
NULLDEV = /dev/null
DEL = $(RM)
RMDIR = $(RM) -r
endif
ifdef CC65_HOME
AS = $(CC65_HOME)/bin/ca65
CC = $(CC65_HOME)/bin/cc65
CL = $(CC65_HOME)/bin/cl65
LD = $(CC65_HOME)/bin/ld65
else
AS := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65)
CC := $(if $(wildcard ../../bin/cc65*),../../bin/cc65,cc65)
CL := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
endif
EXELIST_c64 = \
cbm_working_screen_test.prg
ifneq ($(EXELIST_$(SYS)),)
testcode: $(EXELIST_$(SYS))
else
testcode: notavailable
endif
# empty target used to skip systems that will not work with any program in this dir
notavailable:
ifeq ($(MAKELEVEL),0)
@echo "info: atari tests not available for" $(SYS)
else
# suppress the "nothing to be done for 'testcode' message
@echo > $(NULLDEV)
endif
cbm_working_screen_test.prg: cbm_working_screen_test.c pet2scrcode.s
$(CL) -t c64 -o $@ $? ../../lib/$(SYS).lib
clean:
@$(DEL) cbm_working_screen_test.prg 2>$(NULLDEV)

View File

@ -0,0 +1,128 @@
/* this program prints a text onto the standard screen (e.g. for C64 at $0400) and then switches the
working screen to another location and prints a string there. Then it checks, if both strings are found
at the correct memory location */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <assert.h>
#include "../../include/cbm.h"
char petscii2scrcode(char ch);
int test_boundaries(void)
{
struct testdata {
unsigned char screen_hi;
int returncode;
};
struct testdata testdata_input[] = {
0x00, EXIT_FAILURE,
0x04, EXIT_SUCCESS,
0x0c, EXIT_SUCCESS,
0x10, EXIT_FAILURE, // Cannot set screen to $1000-$1c00 due to shadowing
0x1c, EXIT_FAILURE,
0x20, EXIT_SUCCESS,
0x8c, EXIT_SUCCESS,
0x90, EXIT_FAILURE, // Cannot set screen to $9000-$9c00 due to shadowing
0x9c, EXIT_FAILURE,
0xa0, EXIT_SUCCESS,
0xc0, EXIT_SUCCESS,
0x02, EXIT_FAILURE, // SCREEN not aligned to $0400 boundary
0x41, EXIT_FAILURE,
0x72, EXIT_FAILURE,
0xc3, EXIT_FAILURE,
};
int i, returncode;
printf("Testing different desired workscreen destinations:\n");
for (i = sizeof(testdata_input)/sizeof(testdata_input[0]) - 1; i>=0; --i){
printf("Screen @$%04x: ", testdata_input[i].screen_hi*0x100);
returncode = cbm_set_working_screen(testdata_input[i].screen_hi);
cbm_set_working_screen(0x04);
if (returncode == EXIT_SUCCESS){
printf("OK\n");
} else {
printf("DENY\n");
}
if (returncode != testdata_input[i].returncode){
printf(
"Boundary check failed on screen hi %hhx!\n"
"Function cbm_set_working_screen returned %d instead of %d\n",
testdata_input[i].screen_hi,
returncode, testdata_input[i].returncode);
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}
int str_to_scrcode(char *str){
char* ch_ptr = str;
for (;*ch_ptr != '\0'; ++ch_ptr){
*ch_ptr = petscii2scrcode(*ch_ptr);
}
return 0;
}
int test_str_found_at(char *test_str, uint8_t scr_loc){
cbm_set_working_screen(scr_loc);
putchar(CH_HOME + 0x80);
puts(test_str);
str_to_scrcode(test_str);
cbm_set_working_screen(0x04);
if (strnicmp(test_str, (char*)(scr_loc * 0x100), strlen(test_str)) != 0){
printf("Failed to print to screen location at %04x", scr_loc * 0x100);
return -1;
}
return 0;
}
int main(void)
{
char *test_string1 = "foo";
char *test_string2 = "bar";
size_t testcase_count = 3;
size_t i;
int returncode, failed_tests = 0;
for (i = testcase_count; i>0; --i){
switch(i){
case 3:
returncode = test_boundaries();
break;
case 2:
returncode = test_str_found_at(test_string1, 0x3c);
break;
case 1:
returncode = test_str_found_at(test_string2, 0xc0);
break;
default:
assert(0); // Should never come here
}
if (returncode == EXIT_FAILURE){
++failed_tests;
}
}
return failed_tests;
}

View File

@ -0,0 +1,39 @@
.export _petscii2scrcode
_petscii2scrcode:
cmp #$20 ; if A<32 then...
bcc ddRev
cmp #$60 ; if A<96 then...
bcc dd1
cmp #$80 ; if A<128 then...
bcc dd2
cmp #$a0 ; if A<160 then...
bcc dd3
cmp #$c0 ; if A<192 then...
bcc dd4
cmp #$ff ; if A<255 then...
bcc ddRev
lda #$7e ; A=255, then A=126
bne ddEnd
dd2: and #$5f ; if A=96..127 then strip bits 5 and 7
bne ddEnd
dd3: ora #$40 ; if A=128..159, then set bit 6
bne ddEnd
dd4: eor #$c0 ; if A=160..191 then flip bits 6 and 7
bne ddEnd
dd1: and #$3f ; if A=32..95 then strip bits 6 and 7
bpl ddEnd ; <- you could also do .byte $0c here
ddRev: eor #$80 ; flip bit 7 (reverse on when off and vice versa)
ddEnd: rts