mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-05 21:30:52 +00:00
Merged https://gitlab.com/mark.j.fisher/kickc/-/tree/conio-atari ATARI XL/XE conio.h implementation. Closes #546
This commit is contained in:
commit
482811f2c8
2
.gitignore
vendored
2
.gitignore
vendored
@ -6,4 +6,6 @@
|
||||
*/bin/
|
||||
*/workspace.xml
|
||||
./target/
|
||||
target/
|
||||
**/.DS_Store
|
||||
.project
|
||||
|
@ -1,4 +1,4 @@
|
||||
//KICKC FRAGMENT CACHE 11224357a0 11224372f6
|
||||
//KICKC FRAGMENT CACHE 110cb2b103 110cb2cc7a
|
||||
//FRAGMENT vbuz1=vbuc1
|
||||
lda #{c1}
|
||||
sta {z1}
|
||||
|
@ -1,4 +1,4 @@
|
||||
//KICKC FRAGMENT CACHE 11224357a0 11224372f6
|
||||
//KICKC FRAGMENT CACHE 110cb2b103 110cb2cc7a
|
||||
//FRAGMENT _deref_pbuc1=vbuc2
|
||||
lda #{c2}
|
||||
sta {c1}
|
||||
|
@ -1,4 +1,4 @@
|
||||
//KICKC FRAGMENT CACHE 11224357a0 11224372f6
|
||||
//KICKC FRAGMENT CACHE 110cb2b103 110cb2cc7a
|
||||
//FRAGMENT vbuz1=vbuc1
|
||||
lda #{c1}
|
||||
sta {z1}
|
||||
|
110
src/main/fragment/cache/fragment-cache-mos6502x.asm
vendored
110
src/main/fragment/cache/fragment-cache-mos6502x.asm
vendored
@ -1,4 +1,4 @@
|
||||
//KICKC FRAGMENT CACHE 11224357a0 11224372f6
|
||||
//KICKC FRAGMENT CACHE 110cb2b103 110cb2cc7a
|
||||
//FRAGMENT vbuz1=vbuc1
|
||||
lda #{c1}
|
||||
sta {z1}
|
||||
@ -8902,11 +8902,6 @@ sty {z1}
|
||||
txa
|
||||
sta {z1}+1
|
||||
sty {z1}
|
||||
//FRAGMENT _deref_qbuc1=pbuc2
|
||||
lda #<{c2}
|
||||
sta {c1}
|
||||
lda #>{c2}
|
||||
sta {c1}+1
|
||||
//FRAGMENT _deref_pbsc1=vbsc2
|
||||
lda #{c2}
|
||||
sta {c1}
|
||||
@ -9297,6 +9292,11 @@ tax
|
||||
stx $ff
|
||||
cpy $ff
|
||||
bne {la1}
|
||||
//FRAGMENT _deref_qbuc1=pbuc2
|
||||
lda #<{c2}
|
||||
sta {c1}
|
||||
lda #>{c2}
|
||||
sta {c1}+1
|
||||
//FRAGMENT pwuz1_derefidx_vbuc1=vwuz2
|
||||
ldy #{c1}
|
||||
lda {z2}
|
||||
@ -18829,3 +18829,101 @@ sta {c1},x
|
||||
lda #{c2}
|
||||
ora {c1},y
|
||||
sta {c1},y
|
||||
//FRAGMENT _deref_pwuc1=vbuz1
|
||||
lda {z1}
|
||||
sta {c1}
|
||||
lda #0
|
||||
sta {c1}+1
|
||||
//FRAGMENT pvoz1=_deref_qvoc1
|
||||
lda {c1}
|
||||
sta {z1}
|
||||
lda {c1}+1
|
||||
sta {z1}+1
|
||||
//FRAGMENT _deref_(_deref_qbuc1)=_deref_pbuc2
|
||||
lda {c2}
|
||||
ldy {c1}
|
||||
sty $fe
|
||||
ldy {c1}+1
|
||||
sty $ff
|
||||
ldy #0
|
||||
sta ($fe),y
|
||||
//FRAGMENT vbuz1=pbuc1_derefidx_(_deref_pbuc2)
|
||||
ldy {c2}
|
||||
lda {c1},y
|
||||
sta {z1}
|
||||
//FRAGMENT _deref_pwuc1=_inc__deref_pwuc1
|
||||
inc {c1}
|
||||
bne !+
|
||||
inc {c1}+1
|
||||
!:
|
||||
//FRAGMENT _deref_pwuc1_eq_vbuc2_then_la1
|
||||
lda {c1}+1
|
||||
bne !+
|
||||
lda {c1}
|
||||
cmp #{c2}
|
||||
beq {la1}
|
||||
!:
|
||||
//FRAGMENT pbuz1=_deref_qbuc1_plus_vwuz2
|
||||
clc
|
||||
lda {z2}
|
||||
adc {c1}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
adc {c1}+1
|
||||
sta {z1}+1
|
||||
//FRAGMENT pbuz1=pbuz2_plus__deref_pwuc1
|
||||
clc
|
||||
lda {c1}
|
||||
adc {z2}
|
||||
sta {z1}
|
||||
lda {c1}+1
|
||||
adc {z2}+1
|
||||
sta {z1}+1
|
||||
//FRAGMENT _deref_(_deref_qbuc1)=_deref_(_deref_qbuc1)_bxor_vbuc2
|
||||
ldy {c1}
|
||||
sty $fe
|
||||
ldy {c1}+1
|
||||
sty $ff
|
||||
ldy #0
|
||||
lda ($fe),y
|
||||
eor #{c2}
|
||||
sta ($fe),y
|
||||
//FRAGMENT _deref_pwuc1=vbuaa
|
||||
sta {c1}
|
||||
lda #0
|
||||
sta {c1}+1
|
||||
//FRAGMENT _deref_pwuc1=vbuxx
|
||||
txa
|
||||
sta {c1}
|
||||
lda #0
|
||||
sta {c1}+1
|
||||
//FRAGMENT _deref_pwuc1=vbuyy
|
||||
tya
|
||||
sta {c1}
|
||||
lda #0
|
||||
sta {c1}+1
|
||||
//FRAGMENT vbuaa=pbuc1_derefidx_(_deref_pbuc2)
|
||||
ldy {c2}
|
||||
lda {c1},y
|
||||
//FRAGMENT vbuxx=pbuc1_derefidx_(_deref_pbuc2)
|
||||
ldy {c2}
|
||||
ldx {c1},y
|
||||
//FRAGMENT vbuyy=pbuc1_derefidx_(_deref_pbuc2)
|
||||
ldx {c2}
|
||||
ldy {c1},x
|
||||
//FRAGMENT pbuz1=_deref_qbuc1_plus_vwuz1
|
||||
clc
|
||||
lda {z1}
|
||||
adc {c1}
|
||||
sta {z1}
|
||||
lda {z1}+1
|
||||
adc {c1}+1
|
||||
sta {z1}+1
|
||||
//FRAGMENT pbuz1=pbuz1_plus__deref_pwuc1
|
||||
clc
|
||||
lda {c1}
|
||||
adc {z1}
|
||||
sta {z1}
|
||||
lda {c1}+1
|
||||
adc {z1}+1
|
||||
sta {z1}+1
|
||||
|
@ -1,4 +1,4 @@
|
||||
//KICKC FRAGMENT CACHE 11224357a0 11224372f6
|
||||
//KICKC FRAGMENT CACHE 110cb2b103 110cb2cc7a
|
||||
//FRAGMENT vbuz1=_deref_pbuc1
|
||||
lda {c1}
|
||||
sta {z1}
|
||||
|
@ -0,0 +1,8 @@
|
||||
ldy {c1}
|
||||
sty $fe
|
||||
ldy {c1}+1
|
||||
sty $ff
|
||||
ldy #0
|
||||
lda ($fe),y
|
||||
eor #{c2}
|
||||
sta ($fe),y
|
@ -0,0 +1,9 @@
|
||||
pha
|
||||
ldy #1
|
||||
lda ({z1}),y
|
||||
sta $ff
|
||||
dey
|
||||
lda ({z1}),y
|
||||
sta $fe
|
||||
pla
|
||||
sta ($fe),y
|
@ -0,0 +1,6 @@
|
||||
lda {c1}+1
|
||||
bne !+
|
||||
lda {c1}
|
||||
cmp #{c2}
|
||||
beq {la1}
|
||||
!:
|
@ -0,0 +1,5 @@
|
||||
lda {c1}+1
|
||||
bne {la1}
|
||||
lda {c1}
|
||||
cmp #{c2}
|
||||
bne {la1}
|
@ -0,0 +1,7 @@
|
||||
ldy {c1}
|
||||
sty $fe
|
||||
ldy {c1}+1
|
||||
sty $ff
|
||||
ldy #0
|
||||
lda ($fe),y
|
||||
eor #{c2}
|
@ -0,0 +1,2 @@
|
||||
lda {c1}
|
||||
and #{c2}
|
@ -20,23 +20,63 @@ struct ATARI_POKEY_READ * const POKEY_READ = 0xd200;
|
||||
// Atari ANTIC registers
|
||||
struct ATARI_ANTIC * const ANTIC = 0xd400;
|
||||
|
||||
// Atari OS Shadow registers
|
||||
|
||||
// Atari ZP registers
|
||||
// 1-byte cursor row
|
||||
char * ROWCRS = 0x54;
|
||||
// 2-byte cursor column
|
||||
word * COLCRS = 0x55;
|
||||
// 2-byte saved memory scan counter
|
||||
char ** const SAVMSC = 0x58;
|
||||
// data under cursor
|
||||
char * const OLDCHR = 0x5D;
|
||||
// 2-byte saved cursor memory address
|
||||
char ** const OLDADR = 0x5E;
|
||||
|
||||
// Atari OS Shadow registers
|
||||
// OS Shadow ANTIC Direct Memory Access Control ($D400)
|
||||
char * const SDMCTL = 0x022f;
|
||||
|
||||
// OS Shadow ANTIC Character Control ($D401)
|
||||
char * const CHART = 0x02f3;
|
||||
|
||||
// OS Shadow ANTIC Display List Pointer ($D402)
|
||||
char ** const SDLST = 0x0230;
|
||||
|
||||
// OS Shadow ANTIC Character Set Base Address (D409)
|
||||
char * CHBAS = 0x02f4;
|
||||
|
||||
// OS Shadow ANTIC Light Pen Horizontal Position ($D40C)
|
||||
char * LPENH = 0x234;
|
||||
|
||||
// OS Shadow ANTIC Light Pen Vertical Position ($D40D)
|
||||
char * LPENV = 0x235;
|
||||
// Color register zero, color of playfield zero. Shadow for 53270 ($D016)
|
||||
char * const COLOR0 = 0x2C4;
|
||||
// Shadow for 53271 ($D017). Text color in Gr.0
|
||||
char * const COLOR1 = 0x2C5;
|
||||
// Shadow for 53272 ($D018). Background color in GR.0
|
||||
char * const COLOR2 = 0x2C6;
|
||||
// Shadow for 53273 ($D019)
|
||||
char * const COLOR3 = 0x2C7;
|
||||
// Shadow for 53274 ($D01A). Border color in GR.0
|
||||
char * const COLOR4 = 0x2C8;
|
||||
// Cursor inhibit flag, 0 turns on, any other number turns off. Cursor doesn't change until it moves next.
|
||||
char * const CRSINH = 0x2F0;
|
||||
// Internal hardware value for the last key pressed. Set to 0xFF to clear.
|
||||
char * const CH = 0x2FC;
|
||||
|
||||
// Atari colours - names from Mapping the Atari.
|
||||
// Add luminance values 0-14 (even only) to increase brightness
|
||||
const char BLACK = 0x00;
|
||||
const char RUST = 0x10;
|
||||
const char RED_ORANGE = 0x20;
|
||||
const char DARK_ORANGE = 0x30;
|
||||
const char RED = 0x40;
|
||||
const char DARK_LAVENDER = 0x50;
|
||||
const char COBALT_BLUE = 0x60;
|
||||
const char ULTRAMARINE = 0x70;
|
||||
const char MEDIUM_BLUE = 0x80;
|
||||
const char DARK_BLUE = 0x90;
|
||||
const char BLUE_GREY = 0xA0;
|
||||
const char OLIVE_GREEN = 0xB0;
|
||||
const char MEDIUM_GREEN = 0xC0;
|
||||
const char DARK_GREEN = 0xD0;
|
||||
const char ORANGE_GREEN = 0xE0;
|
||||
const char ORANGE = 0xF0;
|
||||
const char WHITE = 0xFE;
|
||||
|
@ -60,6 +60,6 @@ unsigned char kbhit (void);
|
||||
unsigned char cursor(unsigned char onoff);
|
||||
|
||||
// If onoff is 1, scrolling is enabled when outputting past the end of the screen
|
||||
// If onoff is 1, scrolling is disabled and the cursor instead moves to (0,0)
|
||||
// If onoff is 0, scrolling is disabled and the cursor instead moves to (0,0)
|
||||
// The function returns the old scroll setting.
|
||||
unsigned char scroll(unsigned char onoff);
|
241
src/main/kc/lib/conio-atarixl.c
Normal file
241
src/main/kc/lib/conio-atarixl.c
Normal file
@ -0,0 +1,241 @@
|
||||
// Atari XL conio.h implementation
|
||||
// Created by Mark Fisher @mark.j.fisher @fenrock https://atariage.com/forums/profile/73491-fenrock/
|
||||
// https://gitlab.com/mark.j.fisher/kickc/-/tree/conio-atari
|
||||
#include <string.h>
|
||||
#include <conio.h>
|
||||
#include <atari-xl.h>
|
||||
|
||||
// The screen width
|
||||
#define CONIO_WIDTH 40
|
||||
// The screen height
|
||||
#define CONIO_HEIGHT 24
|
||||
|
||||
// The current reverse value indicator. Values 0 or 0x80 for reverse text
|
||||
__ma char conio_reverse_value = 0;
|
||||
|
||||
// The current cursor enable flag. 1 = on, 0 = off.
|
||||
__ma char conio_display_cursor = 1;
|
||||
|
||||
// The current scroll enable flag. 1 = on, 0 = off.
|
||||
__ma char conio_scroll_enable = 1;
|
||||
|
||||
// Move cursor and output one character
|
||||
// Same as "gotoxy (x, y); cputc (c);"
|
||||
void cputcxy(unsigned char x, unsigned char y, char c) {
|
||||
gotoxy(x, y);
|
||||
cputc(c);
|
||||
}
|
||||
|
||||
// Output one character at the current cursor position
|
||||
// Moves the cursor forward. Scrolls the entire screen if needed
|
||||
void cputc(char c) {
|
||||
char screenCode;
|
||||
if (c == '\r') { // 0x0d, CR = just set the cursor x value to 0
|
||||
*COLCRS = 0;
|
||||
setcursor();
|
||||
} else if(c == '\n' || c == 0x9b) { // 0x0a LF, or atascii EOL
|
||||
*COLCRS = 0;
|
||||
newline();
|
||||
} else {
|
||||
putchar(convertToScreenCode(&c));
|
||||
(*COLCRS)++;
|
||||
if (*COLCRS == CONIO_WIDTH) {
|
||||
*COLCRS = 0;
|
||||
newline();
|
||||
} else {
|
||||
setcursor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Puts a character to the screen a the current location. Uses internal screencode. Deals with storing the old cursor value
|
||||
void putchar(unsigned char code) {
|
||||
**OLDADR = *OLDCHR;
|
||||
char * loc = cursorLocation();
|
||||
char newChar = code | conio_reverse_value;
|
||||
*loc = newChar;
|
||||
*OLDCHR = newChar;
|
||||
setcursor();
|
||||
}
|
||||
|
||||
// Output a NUL-terminated string at the current cursor position
|
||||
void cputs(const char* s) {
|
||||
char c;
|
||||
while (c = *s++) {
|
||||
cputc(c);
|
||||
}
|
||||
}
|
||||
|
||||
// Move cursor and output a NUL-terminated string
|
||||
// Same as "gotoxy (x, y); puts (s);"
|
||||
void cputsxy(unsigned char x, unsigned char y, const char* s) {
|
||||
gotoxy(x, y);
|
||||
cputs(s);
|
||||
}
|
||||
|
||||
// Return a pointer to the location of the cursor
|
||||
char * cursorLocation() {
|
||||
return *SAVMSC + (word)(*ROWCRS)*CONIO_WIDTH + *COLCRS;
|
||||
}
|
||||
|
||||
void newline() {
|
||||
if ((*ROWCRS)++ == CONIO_HEIGHT) {
|
||||
if (conio_scroll_enable == 1) {
|
||||
// first hide the current screen cursor, so it doesn't scroll, but only if it is on
|
||||
if (conio_display_cursor == 1) {
|
||||
**OLDADR ^= 0x80;
|
||||
}
|
||||
// move screen up 1 line
|
||||
char * start = *SAVMSC;
|
||||
memcpy(start, start + CONIO_WIDTH, CONIO_WIDTH * 23);
|
||||
memset(start + CONIO_WIDTH * 23, 0x00, CONIO_WIDTH);
|
||||
*ROWCRS = CONIO_HEIGHT - 1;
|
||||
} else {
|
||||
gotoxy(0, 0);
|
||||
}
|
||||
}
|
||||
setcursor();
|
||||
}
|
||||
|
||||
// Handles cursor movement, displaying it if required, and inverting character it is over if there is one (and enabled)
|
||||
void setcursor() {
|
||||
// save the current oldchr into oldadr
|
||||
**OLDADR = *OLDCHR;
|
||||
// work out the new location for oldadr based on new column/row
|
||||
char * loc = cursorLocation();
|
||||
char c = *loc;
|
||||
*OLDCHR = c;
|
||||
*OLDADR = loc;
|
||||
if (conio_display_cursor == 0) {
|
||||
// cursor is off, don't affect the character at all, but do turn off cursor
|
||||
*CRSINH = 1;
|
||||
} else {
|
||||
// cursor is on, so invert the inverse bit and turn cursor on
|
||||
*CRSINH = 0;
|
||||
c = c ^ 0x80;
|
||||
}
|
||||
**OLDADR = c;
|
||||
}
|
||||
|
||||
// Print a newline
|
||||
void cputln() {
|
||||
*COLCRS = 0;
|
||||
newline();
|
||||
}
|
||||
|
||||
// Set the cursor to the specified position
|
||||
void gotoxy(unsigned char x, unsigned char y) {
|
||||
*COLCRS = x;
|
||||
*ROWCRS = y;
|
||||
setcursor();
|
||||
}
|
||||
|
||||
// Sets reverse mode for text. 1 enables reverse, 0 disables. Returns the old value.
|
||||
unsigned char revers(unsigned char onoff) {
|
||||
char old = conio_reverse_value;
|
||||
if (onoff == 0) conio_reverse_value = 0; else conio_reverse_value = 0x80;
|
||||
return old;
|
||||
}
|
||||
|
||||
// If onoff is 1, scrolling is enabled when outputting past the end of the screen
|
||||
// If onoff is 0, scrolling is disabled and the cursor instead moves to (0,0)
|
||||
// The function returns the old scroll setting.
|
||||
unsigned char scroll(unsigned char onoff) {
|
||||
char old = conio_scroll_enable;
|
||||
conio_scroll_enable = onoff;
|
||||
return old;
|
||||
}
|
||||
|
||||
// clears the screen and moves the cursor to the upper left-hand corner of the screen.
|
||||
void clrscr() {
|
||||
// Fill entire screen with spaces
|
||||
memset(*SAVMSC, 0x00, CONIO_WIDTH * CONIO_HEIGHT); // 0x00 is screencode for space character
|
||||
// set the old character to a space so the cursor doesn't reappear at the last position it was at
|
||||
*OLDCHR = 0x00;
|
||||
gotoxy(0,0);
|
||||
}
|
||||
|
||||
// If onoff is 1, a cursor is displayed when any text is output.
|
||||
// If onoff is 0, the cursor is hidden instead.
|
||||
unsigned char cursor(unsigned char onoff) {
|
||||
// this just updates internal cursor flag value, doesn't update CRSINH
|
||||
// onoff: 0 => cursor off, 1 => cursor on
|
||||
// CRSINH is opposite to this, 0 == ON, 1 == OFF
|
||||
char oldValue = conio_display_cursor;
|
||||
conio_display_cursor = onoff;
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
// Return the X position of the cursor
|
||||
unsigned char wherex() {
|
||||
return (*COLCRS & 0xff);
|
||||
}
|
||||
|
||||
// Return the Y position of the cursor
|
||||
unsigned char wherey() {
|
||||
return *ROWCRS;
|
||||
}
|
||||
|
||||
// Return the current screen size.
|
||||
void screensize(unsigned char *x, unsigned char *y) {
|
||||
*x = CONIO_WIDTH;
|
||||
*y = CONIO_HEIGHT;
|
||||
}
|
||||
|
||||
// Return the current screen size X width.
|
||||
char screensizex() {
|
||||
return CONIO_WIDTH;
|
||||
}
|
||||
|
||||
// Return the current screen size Y height.
|
||||
char screensizey() {
|
||||
return CONIO_HEIGHT;
|
||||
}
|
||||
|
||||
// Return 1 if there's a key waiting, return 0 if not
|
||||
unsigned char kbhit() {
|
||||
if (*CH == 0xff) return 0; else return 1;
|
||||
}
|
||||
|
||||
// Clears the key waiting buffer.
|
||||
inline void clrkb() {
|
||||
*CH = 0xff;
|
||||
}
|
||||
|
||||
// Set the color for the text. The old color setting is returned.
|
||||
unsigned char textcolor(unsigned char color) {
|
||||
char old = *COLOR1;
|
||||
*COLOR1 = color;
|
||||
return old;
|
||||
}
|
||||
|
||||
// Set the color for the background. The old color setting is returned.
|
||||
unsigned char bgcolor(unsigned char color) {
|
||||
char old = *COLOR2;
|
||||
*COLOR2 = color;
|
||||
return old;
|
||||
}
|
||||
|
||||
// Set the color for the border. The old color setting is returned.
|
||||
unsigned char bordercolor(unsigned char color) {
|
||||
char old = *COLOR4;
|
||||
*COLOR4 = color;
|
||||
return old;
|
||||
}
|
||||
|
||||
// Convert an atascii character to its screen code representation. Requires 1 page lookup table generated below.
|
||||
inline unsigned char convertToScreenCode(unsigned char* v) {
|
||||
return rawmap[*v];
|
||||
}
|
||||
|
||||
// create a static table to map char value to screen value
|
||||
// use KickAsm functions to create a table of code -> screen code values, using cc65 algorithm
|
||||
char rawmap[0x100] = kickasm {{
|
||||
.var ht = Hashtable().put(0,64, 1,0, 2,32, 3,96) // the table for converting bit 6,7 into ora value
|
||||
.for(var i=0; i<256; i++) {
|
||||
.var idx = (i & $60) / 32
|
||||
.var mask = i & $9f
|
||||
.byte mask | ht.get(idx)
|
||||
}
|
||||
}};
|
||||
|
@ -160,7 +160,7 @@ unsigned char cursor(unsigned char onoff) {
|
||||
}
|
||||
|
||||
// If onoff is 1, scrolling is enabled when outputting past the end of the screen
|
||||
// If onoff is 1, scrolling is disabled and the cursor instead moves to (0,0)
|
||||
// If onoff is 0, scrolling is disabled and the cursor instead moves to (0,0)
|
||||
// The function returns the old scroll setting.
|
||||
unsigned char scroll(unsigned char onoff) {
|
||||
char old = conio_scroll_enable;
|
||||
|
@ -169,7 +169,7 @@ unsigned char cursor(unsigned char onoff) {
|
||||
}
|
||||
|
||||
// If onoff is 1, scrolling is enabled when outputting past the end of the screen
|
||||
// If onoff is 1, scrolling is disabled and the cursor instead moves to (0,0)
|
||||
// If onoff is 0, scrolling is disabled and the cursor instead moves to (0,0)
|
||||
// The function returns the old scroll setting.
|
||||
unsigned char scroll(unsigned char onoff) {
|
||||
char old = conio_scroll_enable;
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "conio-mega65.c"
|
||||
#elif defined(__NES__)
|
||||
#include "conio-nes.c"
|
||||
#elif defined(__ATARIXL__)
|
||||
#include "conio-atarixl.c"
|
||||
#else
|
||||
#error "Target platform does not support conio.h"
|
||||
#endif
|
||||
|
@ -394,6 +394,11 @@ public class TestPrograms {
|
||||
compileAndCompare("examples/mega65/raster65.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAtariXlConioTest() throws IOException, URISyntaxException {
|
||||
compileAndCompare("examples/atarixl/conio-test.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAtariXlRasterbars() throws IOException, URISyntaxException {
|
||||
compileAndCompare("examples/atarixl/rasterbars.c");
|
||||
|
56
src/test/kc/examples/atarixl/conio-test.c
Normal file
56
src/test/kc/examples/atarixl/conio-test.c
Normal file
@ -0,0 +1,56 @@
|
||||
// Example usages of conio for Atari XL target.
|
||||
|
||||
#pragma target(atarixl)
|
||||
#pragma encoding(atascii)
|
||||
#pragma zp_reserve(0x00..0x7f)
|
||||
|
||||
#include <atari-xl.h>
|
||||
#include <printf.h>
|
||||
#include <conio.h>
|
||||
|
||||
void main() {
|
||||
// hide the cursor
|
||||
cursor(0);
|
||||
|
||||
// change colors
|
||||
bgcolor(DARK_ORANGE);
|
||||
bordercolor(MEDIUM_BLUE);
|
||||
textcolor(WHITE);
|
||||
|
||||
// print some text at a location
|
||||
cputsxy(0, 1, "Hello, World!\n");
|
||||
|
||||
// skip a line
|
||||
gotoxy(0, 3);
|
||||
|
||||
// set inverse text and use printf to output a string
|
||||
revers(1);
|
||||
char *name = "Mark";
|
||||
printf("Hello, %s - press a key!\n", name);
|
||||
|
||||
// wait for user keypress
|
||||
waitkey();
|
||||
|
||||
// clear screen
|
||||
clrscr();
|
||||
|
||||
// reset reverse and do some scrolling lines.
|
||||
revers(0);
|
||||
for(int i: 0..50) {
|
||||
printf("Scrolling lines ... %d\n", i);
|
||||
}
|
||||
waitkey();
|
||||
|
||||
// turn scroll off and do more lines
|
||||
scroll(0);
|
||||
for(int i: 51..200) {
|
||||
printf("Some wrapping lines ... %d\n", i);
|
||||
}
|
||||
waitkey();
|
||||
|
||||
}
|
||||
|
||||
void waitkey() {
|
||||
while(!kbhit()) ;
|
||||
clrkb();
|
||||
}
|
948
src/test/ref/examples/atarixl/conio-test.asm
Normal file
948
src/test/ref/examples/atarixl/conio-test.asm
Normal file
@ -0,0 +1,948 @@
|
||||
// Example usages of conio for Atari XL target.
|
||||
// Atari XL/XE executable XEX file with a single segment
|
||||
// https://www.atarimax.com/jindroush.atari.org/afmtexe.html
|
||||
.file [name="conio-test.xex", type="bin", segments="XexFile"]
|
||||
.segmentdef XexFile
|
||||
.segment XexFile
|
||||
// Binary File Header
|
||||
.byte $ff, $ff
|
||||
// Program segment [start address, end address, data]
|
||||
.word ProgramStart, ProgramEnd-1
|
||||
.segmentout [ segments="Program" ]
|
||||
// RunAd - Run Address Segment [start address, end address, data]
|
||||
.word $02e0, $02e1
|
||||
.word __start
|
||||
.segmentdef Program [segments="ProgramStart, Code, Data, ProgramEnd"]
|
||||
.segmentdef ProgramStart [start=$2000]
|
||||
.segment ProgramStart
|
||||
ProgramStart:
|
||||
.segmentdef Code [startAfter="ProgramStart"]
|
||||
.segmentdef Data [startAfter="Code"]
|
||||
.segmentdef ProgramEnd [startAfter="Data"]
|
||||
.segment ProgramEnd
|
||||
ProgramEnd:
|
||||
|
||||
.const DARK_ORANGE = $30
|
||||
.const MEDIUM_BLUE = $80
|
||||
.const WHITE = $fe
|
||||
.const OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS = 1
|
||||
.const SIZEOF_STRUCT_PRINTF_BUFFER_NUMBER = $c
|
||||
// 2-byte saved memory scan counter
|
||||
.label SAVMSC = $58
|
||||
// data under cursor
|
||||
.label OLDCHR = $5d
|
||||
// 2-byte saved cursor memory address
|
||||
.label OLDADR = $5e
|
||||
// Shadow for 53271 ($D017). Text color in Gr.0
|
||||
.label COLOR1 = $2c5
|
||||
// Shadow for 53272 ($D018). Background color in GR.0
|
||||
.label COLOR2 = $2c6
|
||||
// Shadow for 53274 ($D01A). Border color in GR.0
|
||||
.label COLOR4 = $2c8
|
||||
// Cursor inhibit flag, 0 turns on, any other number turns off. Cursor doesn't change until it moves next.
|
||||
.label CRSINH = $2f0
|
||||
// Internal hardware value for the last key pressed. Set to 0xFF to clear.
|
||||
.label CH = $2fc
|
||||
// Atari ZP registers
|
||||
// 1-byte cursor row
|
||||
.label ROWCRS = $54
|
||||
// 2-byte cursor column
|
||||
.label COLCRS = $55
|
||||
// The screen width
|
||||
// The screen height
|
||||
// The current reverse value indicator. Values 0 or 0x80 for reverse text
|
||||
.label conio_reverse_value = $87
|
||||
// The current cursor enable flag. 1 = on, 0 = off.
|
||||
.label conio_display_cursor = $88
|
||||
// The current scroll enable flag. 1 = on, 0 = off.
|
||||
.label conio_scroll_enable = $89
|
||||
.segment Code
|
||||
__start: {
|
||||
// conio_reverse_value = 0
|
||||
lda #0
|
||||
sta.z conio_reverse_value
|
||||
// conio_display_cursor = 1
|
||||
lda #1
|
||||
sta.z conio_display_cursor
|
||||
// conio_scroll_enable = 1
|
||||
sta.z conio_scroll_enable
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.label i = $80
|
||||
.label i1 = $82
|
||||
// cursor(0)
|
||||
// hide the cursor
|
||||
jsr cursor
|
||||
// bgcolor(DARK_ORANGE)
|
||||
// change colors
|
||||
jsr bgcolor
|
||||
// bordercolor(MEDIUM_BLUE)
|
||||
jsr bordercolor
|
||||
// textcolor(WHITE)
|
||||
jsr textcolor
|
||||
// cputsxy(0, 1, "Hello, World!\n")
|
||||
// print some text at a location
|
||||
jsr cputsxy
|
||||
// gotoxy(0, 3)
|
||||
// skip a line
|
||||
ldx #3
|
||||
lda #0
|
||||
jsr gotoxy
|
||||
// revers(1)
|
||||
// set inverse text and use printf to output a string
|
||||
lda #1
|
||||
jsr revers
|
||||
// printf("Hello, %s - press a key!\n", name)
|
||||
lda #<s1
|
||||
sta.z cputs.s
|
||||
lda #>s1
|
||||
sta.z cputs.s+1
|
||||
jsr cputs
|
||||
// printf("Hello, %s - press a key!\n", name)
|
||||
jsr printf_string
|
||||
// printf("Hello, %s - press a key!\n", name)
|
||||
lda #<s2
|
||||
sta.z cputs.s
|
||||
lda #>s2
|
||||
sta.z cputs.s+1
|
||||
jsr cputs
|
||||
// waitkey()
|
||||
// wait for user keypress
|
||||
jsr waitkey
|
||||
// clrscr()
|
||||
// clear screen
|
||||
jsr clrscr
|
||||
// revers(0)
|
||||
// reset reverse and do some scrolling lines.
|
||||
lda #0
|
||||
jsr revers
|
||||
lda #<0
|
||||
sta.z i
|
||||
sta.z i+1
|
||||
__b1:
|
||||
// printf("Scrolling lines ... %d\n", i)
|
||||
lda #<s3
|
||||
sta.z cputs.s
|
||||
lda #>s3
|
||||
sta.z cputs.s+1
|
||||
jsr cputs
|
||||
// printf("Scrolling lines ... %d\n", i)
|
||||
lda.z i
|
||||
sta.z printf_sint.value
|
||||
lda.z i+1
|
||||
sta.z printf_sint.value+1
|
||||
jsr printf_sint
|
||||
// printf("Scrolling lines ... %d\n", i)
|
||||
lda #<s4
|
||||
sta.z cputs.s
|
||||
lda #>s4
|
||||
sta.z cputs.s+1
|
||||
jsr cputs
|
||||
// for(int i: 0..50)
|
||||
inc.z i
|
||||
bne !+
|
||||
inc.z i+1
|
||||
!:
|
||||
lda.z i+1
|
||||
cmp #>$33
|
||||
bne __b1
|
||||
lda.z i
|
||||
cmp #<$33
|
||||
bne __b1
|
||||
// waitkey()
|
||||
jsr waitkey
|
||||
// scroll(0)
|
||||
// turn scroll off and do more lines
|
||||
jsr scroll
|
||||
lda #<$33
|
||||
sta.z i1
|
||||
lda #>$33
|
||||
sta.z i1+1
|
||||
__b3:
|
||||
// printf("Some wrapping lines ... %d\n", i)
|
||||
lda #<s5
|
||||
sta.z cputs.s
|
||||
lda #>s5
|
||||
sta.z cputs.s+1
|
||||
jsr cputs
|
||||
// printf("Some wrapping lines ... %d\n", i)
|
||||
lda.z i1
|
||||
sta.z printf_sint.value
|
||||
lda.z i1+1
|
||||
sta.z printf_sint.value+1
|
||||
jsr printf_sint
|
||||
// printf("Some wrapping lines ... %d\n", i)
|
||||
lda #<s4
|
||||
sta.z cputs.s
|
||||
lda #>s4
|
||||
sta.z cputs.s+1
|
||||
jsr cputs
|
||||
// for(int i: 51..200)
|
||||
inc.z i1
|
||||
bne !+
|
||||
inc.z i1+1
|
||||
!:
|
||||
lda.z i1+1
|
||||
cmp #>$c9
|
||||
bne __b3
|
||||
lda.z i1
|
||||
cmp #<$c9
|
||||
bne __b3
|
||||
// waitkey()
|
||||
jsr waitkey
|
||||
// }
|
||||
rts
|
||||
.segment Data
|
||||
.encoding "ascii"
|
||||
name: .text "Mark"
|
||||
.byte 0
|
||||
s: .text @"Hello, World!\$9b"
|
||||
.byte 0
|
||||
s1: .text "Hello, "
|
||||
.byte 0
|
||||
s2: .text @" - press a key!\$9b"
|
||||
.byte 0
|
||||
s3: .text "Scrolling lines ... "
|
||||
.byte 0
|
||||
s4: .text @"\$9b"
|
||||
.byte 0
|
||||
s5: .text "Some wrapping lines ... "
|
||||
.byte 0
|
||||
}
|
||||
.segment Code
|
||||
// If onoff is 1, a cursor is displayed when any text is output.
|
||||
// If onoff is 0, the cursor is hidden instead.
|
||||
cursor: {
|
||||
.const onoff = 0
|
||||
// conio_display_cursor = onoff
|
||||
lda #onoff
|
||||
sta.z conio_display_cursor
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Set the color for the background. The old color setting is returned.
|
||||
bgcolor: {
|
||||
// *COLOR2 = color
|
||||
lda #DARK_ORANGE
|
||||
sta COLOR2
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Set the color for the border. The old color setting is returned.
|
||||
bordercolor: {
|
||||
// *COLOR4 = color
|
||||
lda #MEDIUM_BLUE
|
||||
sta COLOR4
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Set the color for the text. The old color setting is returned.
|
||||
textcolor: {
|
||||
// *COLOR1 = color
|
||||
lda #WHITE
|
||||
sta COLOR1
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Move cursor and output a NUL-terminated string
|
||||
// Same as "gotoxy (x, y); puts (s);"
|
||||
cputsxy: {
|
||||
.const x = 0
|
||||
.const y = 1
|
||||
// gotoxy(x, y)
|
||||
ldx #y
|
||||
lda #x
|
||||
jsr gotoxy
|
||||
// cputs(s)
|
||||
lda #<main.s
|
||||
sta.z cputs.s
|
||||
lda #>main.s
|
||||
sta.z cputs.s+1
|
||||
jsr cputs
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Set the cursor to the specified position
|
||||
// gotoxy(byte register(A) x, byte register(X) y)
|
||||
gotoxy: {
|
||||
// *COLCRS = x
|
||||
sta COLCRS
|
||||
lda #0
|
||||
sta COLCRS+1
|
||||
// *ROWCRS = y
|
||||
stx ROWCRS
|
||||
// setcursor()
|
||||
jsr setcursor
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Sets reverse mode for text. 1 enables reverse, 0 disables. Returns the old value.
|
||||
// revers(byte register(A) onoff)
|
||||
revers: {
|
||||
// if (onoff == 0)
|
||||
cmp #0
|
||||
beq __b1
|
||||
// conio_reverse_value = 0x80
|
||||
lda #$80
|
||||
sta.z conio_reverse_value
|
||||
// }
|
||||
rts
|
||||
__b1:
|
||||
// conio_reverse_value = 0
|
||||
lda #0
|
||||
sta.z conio_reverse_value
|
||||
rts
|
||||
}
|
||||
// Output a NUL-terminated string at the current cursor position
|
||||
// cputs(byte* zp($84) s)
|
||||
cputs: {
|
||||
.label s = $84
|
||||
__b1:
|
||||
// while (c = *s++)
|
||||
ldy #0
|
||||
lda (s),y
|
||||
inc.z s
|
||||
bne !+
|
||||
inc.z s+1
|
||||
!:
|
||||
cmp #0
|
||||
bne __b2
|
||||
// }
|
||||
rts
|
||||
__b2:
|
||||
// cputc(c)
|
||||
sta.z cputc.c
|
||||
jsr cputc
|
||||
jmp __b1
|
||||
}
|
||||
// Print a string value using a specific format
|
||||
// Handles justification and min length
|
||||
printf_string: {
|
||||
// cputs(str)
|
||||
lda #<main.name
|
||||
sta.z cputs.s
|
||||
lda #>main.name
|
||||
sta.z cputs.s+1
|
||||
jsr cputs
|
||||
// }
|
||||
rts
|
||||
}
|
||||
waitkey: {
|
||||
__b1:
|
||||
// kbhit()
|
||||
jsr kbhit
|
||||
// while(!kbhit())
|
||||
cmp #0
|
||||
beq __b1
|
||||
// *CH = 0xff
|
||||
lda #$ff
|
||||
sta CH
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// clears the screen and moves the cursor to the upper left-hand corner of the screen.
|
||||
clrscr: {
|
||||
lda SAVMSC
|
||||
sta.z memset.str
|
||||
lda SAVMSC+1
|
||||
sta.z memset.str+1
|
||||
// memset(*SAVMSC, 0x00, CONIO_WIDTH * CONIO_HEIGHT)
|
||||
// Fill entire screen with spaces
|
||||
lda #<$28*$18
|
||||
sta.z memset.num
|
||||
lda #>$28*$18
|
||||
sta.z memset.num+1
|
||||
jsr memset
|
||||
// *OLDCHR = 0x00
|
||||
// 0x00 is screencode for space character
|
||||
// set the old character to a space so the cursor doesn't reappear at the last position it was at
|
||||
lda #0
|
||||
sta OLDCHR
|
||||
// gotoxy(0,0)
|
||||
tax
|
||||
txa
|
||||
jsr gotoxy
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Print a signed integer using a specific format
|
||||
// printf_sint(signed word zp($84) value)
|
||||
printf_sint: {
|
||||
.label value = $84
|
||||
// printf_buffer.sign = 0
|
||||
// Handle any sign
|
||||
lda #0
|
||||
sta printf_buffer
|
||||
// if(value<0)
|
||||
lda.z value+1
|
||||
bmi __b1
|
||||
jmp __b2
|
||||
__b1:
|
||||
// value = -value
|
||||
sec
|
||||
lda #0
|
||||
sbc.z value
|
||||
sta.z value
|
||||
lda #0
|
||||
sbc.z value+1
|
||||
sta.z value+1
|
||||
// printf_buffer.sign = '-'
|
||||
lda #'-'
|
||||
sta printf_buffer
|
||||
__b2:
|
||||
// utoa(uvalue, printf_buffer.digits, format.radix)
|
||||
jsr utoa
|
||||
// printf_number_buffer(printf_buffer, format)
|
||||
lda printf_buffer
|
||||
// Print using format
|
||||
jsr printf_number_buffer
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// If onoff is 1, scrolling is enabled when outputting past the end of the screen
|
||||
// If onoff is 0, scrolling is disabled and the cursor instead moves to (0,0)
|
||||
// The function returns the old scroll setting.
|
||||
scroll: {
|
||||
.const onoff = 0
|
||||
// conio_scroll_enable = onoff
|
||||
lda #onoff
|
||||
sta.z conio_scroll_enable
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Handles cursor movement, displaying it if required, and inverting character it is over if there is one (and enabled)
|
||||
setcursor: {
|
||||
.label loc = $8b
|
||||
// **OLDADR = *OLDCHR
|
||||
// save the current oldchr into oldadr
|
||||
lda OLDCHR
|
||||
ldy OLDADR
|
||||
sty.z $fe
|
||||
ldy OLDADR+1
|
||||
sty.z $ff
|
||||
ldy #0
|
||||
sta ($fe),y
|
||||
// cursorLocation()
|
||||
jsr cursorLocation
|
||||
// loc = cursorLocation()
|
||||
// c = *loc
|
||||
ldy #0
|
||||
lda (loc),y
|
||||
tax
|
||||
// *OLDCHR = c
|
||||
stx OLDCHR
|
||||
// *OLDADR = loc
|
||||
lda.z loc
|
||||
sta OLDADR
|
||||
lda.z loc+1
|
||||
sta OLDADR+1
|
||||
// if (conio_display_cursor == 0)
|
||||
lda.z conio_display_cursor
|
||||
cmp #0
|
||||
beq __b1
|
||||
// *CRSINH = 0
|
||||
// cursor is on, so invert the inverse bit and turn cursor on
|
||||
tya
|
||||
sta CRSINH
|
||||
// c = c ^ 0x80
|
||||
txa
|
||||
eor #$80
|
||||
tax
|
||||
__b2:
|
||||
// **OLDADR = c
|
||||
txa
|
||||
ldy OLDADR
|
||||
sty.z $fe
|
||||
ldy OLDADR+1
|
||||
sty.z $ff
|
||||
ldy #0
|
||||
sta ($fe),y
|
||||
// }
|
||||
rts
|
||||
__b1:
|
||||
// *CRSINH = 1
|
||||
// cursor is off, don't affect the character at all, but do turn off cursor
|
||||
lda #1
|
||||
sta CRSINH
|
||||
jmp __b2
|
||||
}
|
||||
// Output one character at the current cursor position
|
||||
// Moves the cursor forward. Scrolls the entire screen if needed
|
||||
// cputc(byte zp($8a) c)
|
||||
cputc: {
|
||||
.label convertToScreenCode1_v = c
|
||||
.label c = $8a
|
||||
// if (c == '\r')
|
||||
lda #'\r'
|
||||
cmp.z c
|
||||
beq __b1
|
||||
// if(c == '\n' || c == 0x9b)
|
||||
lda #'\$9b'
|
||||
cmp.z c
|
||||
beq __b2
|
||||
lda #$9b
|
||||
cmp.z c
|
||||
beq __b2
|
||||
// return rawmap[*v];
|
||||
ldy.z convertToScreenCode1_v
|
||||
ldx rawmap,y
|
||||
// putchar(convertToScreenCode(&c))
|
||||
jsr putchar
|
||||
// (*COLCRS)++;
|
||||
inc COLCRS
|
||||
bne !+
|
||||
inc COLCRS+1
|
||||
!:
|
||||
// if (*COLCRS == CONIO_WIDTH)
|
||||
lda COLCRS+1
|
||||
bne !+
|
||||
lda COLCRS
|
||||
cmp #$28
|
||||
beq __b5
|
||||
!:
|
||||
// setcursor()
|
||||
jsr setcursor
|
||||
// }
|
||||
rts
|
||||
__b5:
|
||||
// *COLCRS = 0
|
||||
lda #0
|
||||
sta COLCRS+1
|
||||
sta COLCRS
|
||||
// newline()
|
||||
jsr newline
|
||||
rts
|
||||
__b2:
|
||||
// *COLCRS = 0
|
||||
// 0x0a LF, or atascii EOL
|
||||
lda #0
|
||||
sta COLCRS+1
|
||||
sta COLCRS
|
||||
// newline()
|
||||
jsr newline
|
||||
rts
|
||||
__b1:
|
||||
// *COLCRS = 0
|
||||
// 0x0d, CR = just set the cursor x value to 0
|
||||
lda #0
|
||||
sta COLCRS+1
|
||||
sta COLCRS
|
||||
// setcursor()
|
||||
jsr setcursor
|
||||
rts
|
||||
}
|
||||
// Return 1 if there's a key waiting, return 0 if not
|
||||
kbhit: {
|
||||
// if (*CH == 0xff)
|
||||
lda #$ff
|
||||
cmp CH
|
||||
beq __b1
|
||||
lda #1
|
||||
rts
|
||||
__b1:
|
||||
lda #0
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str.
|
||||
// memset(byte* zp($8d) str, word zp($8b) num)
|
||||
memset: {
|
||||
.label end = $8b
|
||||
.label dst = $8d
|
||||
.label str = $8d
|
||||
.label num = $8b
|
||||
// if(num>0)
|
||||
lda.z num
|
||||
bne !+
|
||||
lda.z num+1
|
||||
beq __breturn
|
||||
!:
|
||||
// end = (char*)str + num
|
||||
lda.z end
|
||||
clc
|
||||
adc.z str
|
||||
sta.z end
|
||||
lda.z end+1
|
||||
adc.z str+1
|
||||
sta.z end+1
|
||||
__b2:
|
||||
// for(char* dst = str; dst!=end; dst++)
|
||||
lda.z dst+1
|
||||
cmp.z end+1
|
||||
bne __b3
|
||||
lda.z dst
|
||||
cmp.z end
|
||||
bne __b3
|
||||
__breturn:
|
||||
// }
|
||||
rts
|
||||
__b3:
|
||||
// *dst = c
|
||||
lda #0
|
||||
tay
|
||||
sta (dst),y
|
||||
// for(char* dst = str; dst!=end; dst++)
|
||||
inc.z dst
|
||||
bne !+
|
||||
inc.z dst+1
|
||||
!:
|
||||
jmp __b2
|
||||
}
|
||||
// Converts unsigned number value to a string representing it in RADIX format.
|
||||
// If the leading digits are zero they are not included in the string.
|
||||
// - value : The number to be converted to RADIX
|
||||
// - buffer : receives the string representing the number and zero-termination.
|
||||
// - radix : The radix to convert the number to (from the enum RADIX)
|
||||
// utoa(word zp($84) value, byte* zp($8b) buffer)
|
||||
utoa: {
|
||||
.label digit_value = $8d
|
||||
.label buffer = $8b
|
||||
.label digit = $86
|
||||
.label value = $84
|
||||
lda #<printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS
|
||||
sta.z buffer
|
||||
lda #>printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS
|
||||
sta.z buffer+1
|
||||
ldx #0
|
||||
txa
|
||||
sta.z digit
|
||||
__b1:
|
||||
// for( char digit=0; digit<max_digits-1; digit++ )
|
||||
lda.z digit
|
||||
cmp #5-1
|
||||
bcc __b2
|
||||
// *buffer++ = DIGITS[(char)value]
|
||||
lda.z value
|
||||
tay
|
||||
lda DIGITS,y
|
||||
ldy #0
|
||||
sta (buffer),y
|
||||
// *buffer++ = DIGITS[(char)value];
|
||||
inc.z buffer
|
||||
bne !+
|
||||
inc.z buffer+1
|
||||
!:
|
||||
// *buffer = 0
|
||||
lda #0
|
||||
tay
|
||||
sta (buffer),y
|
||||
// }
|
||||
rts
|
||||
__b2:
|
||||
// digit_value = digit_values[digit]
|
||||
lda.z digit
|
||||
asl
|
||||
tay
|
||||
lda RADIX_DECIMAL_VALUES,y
|
||||
sta.z digit_value
|
||||
lda RADIX_DECIMAL_VALUES+1,y
|
||||
sta.z digit_value+1
|
||||
// if (started || value >= digit_value)
|
||||
cpx #0
|
||||
bne __b5
|
||||
cmp.z value+1
|
||||
bne !+
|
||||
lda.z digit_value
|
||||
cmp.z value
|
||||
beq __b5
|
||||
!:
|
||||
bcc __b5
|
||||
__b4:
|
||||
// for( char digit=0; digit<max_digits-1; digit++ )
|
||||
inc.z digit
|
||||
jmp __b1
|
||||
__b5:
|
||||
// utoa_append(buffer++, value, digit_value)
|
||||
jsr utoa_append
|
||||
// utoa_append(buffer++, value, digit_value)
|
||||
// value = utoa_append(buffer++, value, digit_value)
|
||||
// value = utoa_append(buffer++, value, digit_value);
|
||||
inc.z buffer
|
||||
bne !+
|
||||
inc.z buffer+1
|
||||
!:
|
||||
ldx #1
|
||||
jmp __b4
|
||||
}
|
||||
// Print the contents of the number buffer using a specific format.
|
||||
// This handles minimum length, zero-filling, and left/right justification from the format
|
||||
// printf_number_buffer(byte register(A) buffer_sign)
|
||||
printf_number_buffer: {
|
||||
.label buffer_digits = printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS
|
||||
// if(buffer.sign)
|
||||
cmp #0
|
||||
beq __b2
|
||||
// cputc(buffer.sign)
|
||||
sta.z cputc.c
|
||||
jsr cputc
|
||||
__b2:
|
||||
// cputs(buffer.digits)
|
||||
lda #<buffer_digits
|
||||
sta.z cputs.s
|
||||
lda #>buffer_digits
|
||||
sta.z cputs.s+1
|
||||
jsr cputs
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Return a pointer to the location of the cursor
|
||||
cursorLocation: {
|
||||
.label __0 = $8b
|
||||
.label __1 = $8b
|
||||
.label __3 = $8b
|
||||
.label return = $8b
|
||||
.label __4 = $8f
|
||||
.label __5 = $8b
|
||||
// (word)(*ROWCRS)*CONIO_WIDTH
|
||||
lda ROWCRS
|
||||
sta.z __3
|
||||
lda #0
|
||||
sta.z __3+1
|
||||
lda.z __3
|
||||
asl
|
||||
sta.z __4
|
||||
lda.z __3+1
|
||||
rol
|
||||
sta.z __4+1
|
||||
asl.z __4
|
||||
rol.z __4+1
|
||||
lda.z __5
|
||||
clc
|
||||
adc.z __4
|
||||
sta.z __5
|
||||
lda.z __5+1
|
||||
adc.z __4+1
|
||||
sta.z __5+1
|
||||
asl.z __0
|
||||
rol.z __0+1
|
||||
asl.z __0
|
||||
rol.z __0+1
|
||||
asl.z __0
|
||||
rol.z __0+1
|
||||
// *SAVMSC + (word)(*ROWCRS)*CONIO_WIDTH
|
||||
clc
|
||||
lda.z __1
|
||||
adc SAVMSC
|
||||
sta.z __1
|
||||
lda.z __1+1
|
||||
adc SAVMSC+1
|
||||
sta.z __1+1
|
||||
// *SAVMSC + (word)(*ROWCRS)*CONIO_WIDTH + *COLCRS
|
||||
clc
|
||||
lda COLCRS
|
||||
adc.z return
|
||||
sta.z return
|
||||
lda COLCRS+1
|
||||
adc.z return+1
|
||||
sta.z return+1
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Puts a character to the screen a the current location. Uses internal screencode. Deals with storing the old cursor value
|
||||
putchar: {
|
||||
.label loc = $8b
|
||||
// **OLDADR = *OLDCHR
|
||||
lda OLDCHR
|
||||
ldy OLDADR
|
||||
sty.z $fe
|
||||
ldy OLDADR+1
|
||||
sty.z $ff
|
||||
ldy #0
|
||||
sta ($fe),y
|
||||
// cursorLocation()
|
||||
jsr cursorLocation
|
||||
// loc = cursorLocation()
|
||||
// newChar = code | conio_reverse_value
|
||||
txa
|
||||
ora.z conio_reverse_value
|
||||
// *loc = newChar
|
||||
ldy #0
|
||||
sta (loc),y
|
||||
// *OLDCHR = newChar
|
||||
sta OLDCHR
|
||||
// setcursor()
|
||||
jsr setcursor
|
||||
// }
|
||||
rts
|
||||
}
|
||||
newline: {
|
||||
.label start = $8d
|
||||
// if ((*ROWCRS)++ == CONIO_HEIGHT)
|
||||
inc ROWCRS
|
||||
lda #$18
|
||||
cmp ROWCRS
|
||||
bne __b1
|
||||
// if (conio_scroll_enable == 1)
|
||||
lda #1
|
||||
cmp.z conio_scroll_enable
|
||||
beq __b4
|
||||
// gotoxy(0, 0)
|
||||
ldx #0
|
||||
txa
|
||||
jsr gotoxy
|
||||
__b1:
|
||||
// setcursor()
|
||||
jsr setcursor
|
||||
// }
|
||||
rts
|
||||
__b4:
|
||||
// if (conio_display_cursor == 1)
|
||||
lda #1
|
||||
cmp.z conio_display_cursor
|
||||
bne __b5
|
||||
// **OLDADR ^= 0x80
|
||||
ldy OLDADR
|
||||
sty.z $fe
|
||||
ldy OLDADR+1
|
||||
sty.z $ff
|
||||
ldy #0
|
||||
lda ($fe),y
|
||||
eor #$80
|
||||
sta ($fe),y
|
||||
__b5:
|
||||
// start = *SAVMSC
|
||||
// move screen up 1 line
|
||||
lda SAVMSC
|
||||
sta.z start
|
||||
lda SAVMSC+1
|
||||
sta.z start+1
|
||||
// start + CONIO_WIDTH
|
||||
lda #$28
|
||||
clc
|
||||
adc.z start
|
||||
sta.z memcpy.source
|
||||
lda #0
|
||||
adc.z start+1
|
||||
sta.z memcpy.source+1
|
||||
// memcpy(start, start + CONIO_WIDTH, CONIO_WIDTH * 23)
|
||||
lda.z start
|
||||
sta.z memcpy.destination
|
||||
lda.z start+1
|
||||
sta.z memcpy.destination+1
|
||||
jsr memcpy
|
||||
// start + CONIO_WIDTH * 23
|
||||
clc
|
||||
lda.z memset.str
|
||||
adc #<$28*$17
|
||||
sta.z memset.str
|
||||
lda.z memset.str+1
|
||||
adc #>$28*$17
|
||||
sta.z memset.str+1
|
||||
// memset(start + CONIO_WIDTH * 23, 0x00, CONIO_WIDTH)
|
||||
lda #<$28
|
||||
sta.z memset.num
|
||||
lda #>$28
|
||||
sta.z memset.num+1
|
||||
jsr memset
|
||||
// *ROWCRS = CONIO_HEIGHT - 1
|
||||
lda #$18-1
|
||||
sta ROWCRS
|
||||
jmp __b1
|
||||
}
|
||||
// Used to convert a single digit of an unsigned number value to a string representation
|
||||
// Counts a single digit up from '0' as long as the value is larger than sub.
|
||||
// Each time the digit is increased sub is subtracted from value.
|
||||
// - buffer : pointer to the char that receives the digit
|
||||
// - value : The value where the digit will be derived from
|
||||
// - sub : the value of a '1' in the digit. Subtracted continually while the digit is increased.
|
||||
// (For decimal the subs used are 10000, 1000, 100, 10, 1)
|
||||
// returns : the value reduced by sub * digit so that it is less than sub.
|
||||
// utoa_append(byte* zp($8b) buffer, word zp($84) value, word zp($8d) sub)
|
||||
utoa_append: {
|
||||
.label buffer = $8b
|
||||
.label value = $84
|
||||
.label sub = $8d
|
||||
.label return = $84
|
||||
ldx #0
|
||||
__b1:
|
||||
// while (value >= sub)
|
||||
lda.z sub+1
|
||||
cmp.z value+1
|
||||
bne !+
|
||||
lda.z sub
|
||||
cmp.z value
|
||||
beq __b2
|
||||
!:
|
||||
bcc __b2
|
||||
// *buffer = DIGITS[digit]
|
||||
lda DIGITS,x
|
||||
ldy #0
|
||||
sta (buffer),y
|
||||
// }
|
||||
rts
|
||||
__b2:
|
||||
// digit++;
|
||||
inx
|
||||
// value -= sub
|
||||
lda.z value
|
||||
sec
|
||||
sbc.z sub
|
||||
sta.z value
|
||||
lda.z value+1
|
||||
sbc.z sub+1
|
||||
sta.z value+1
|
||||
jmp __b1
|
||||
}
|
||||
// Copy block of memory (forwards)
|
||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
||||
// memcpy(void* zp($8f) destination, byte* zp($8b) source)
|
||||
memcpy: {
|
||||
.const num = $28*$17
|
||||
.label src_end = $91
|
||||
.label dst = $8f
|
||||
.label src = $8b
|
||||
.label destination = $8f
|
||||
.label source = $8b
|
||||
// src_end = (char*)source+num
|
||||
clc
|
||||
lda.z source
|
||||
adc #<num
|
||||
sta.z src_end
|
||||
lda.z source+1
|
||||
adc #>num
|
||||
sta.z src_end+1
|
||||
__b1:
|
||||
// while(src!=src_end)
|
||||
lda.z src+1
|
||||
cmp.z src_end+1
|
||||
bne __b2
|
||||
lda.z src
|
||||
cmp.z src_end
|
||||
bne __b2
|
||||
// }
|
||||
rts
|
||||
__b2:
|
||||
// *dst++ = *src++
|
||||
ldy #0
|
||||
lda (src),y
|
||||
sta (dst),y
|
||||
// *dst++ = *src++;
|
||||
inc.z dst
|
||||
bne !+
|
||||
inc.z dst+1
|
||||
!:
|
||||
inc.z src
|
||||
bne !+
|
||||
inc.z src+1
|
||||
!:
|
||||
jmp __b1
|
||||
}
|
||||
.segment Data
|
||||
// The digits used for numbers
|
||||
DIGITS: .text "0123456789abcdef"
|
||||
// Values of decimal digits
|
||||
RADIX_DECIMAL_VALUES: .word $2710, $3e8, $64, $a
|
||||
// create a static table to map char value to screen value
|
||||
// use KickAsm functions to create a table of code -> screen code values, using cc65 algorithm
|
||||
rawmap:
|
||||
.var ht = Hashtable().put(0,64, 1,0, 2,32, 3,96) // the table for converting bit 6,7 into ora value
|
||||
.for(var i=0; i<256; i++) {
|
||||
.var idx = (i & $60) / 32
|
||||
.var mask = i & $9f
|
||||
.byte mask | ht.get(idx)
|
||||
}
|
||||
|
||||
// Buffer used for stringified number being printed
|
||||
printf_buffer: .fill SIZEOF_STRUCT_PRINTF_BUFFER_NUMBER, 0
|
563
src/test/ref/examples/atarixl/conio-test.cfg
Normal file
563
src/test/ref/examples/atarixl/conio-test.cfg
Normal file
@ -0,0 +1,563 @@
|
||||
|
||||
void __start()
|
||||
__start: scope:[__start] from
|
||||
[0] phi()
|
||||
to:__start::__init1
|
||||
__start::__init1: scope:[__start] from __start
|
||||
[1] conio_reverse_value = 0
|
||||
[2] conio_display_cursor = 1
|
||||
[3] conio_scroll_enable = 1
|
||||
to:__start::@1
|
||||
__start::@1: scope:[__start] from __start::__init1
|
||||
[4] phi()
|
||||
[5] call main
|
||||
to:__start::@return
|
||||
__start::@return: scope:[__start] from __start::@1
|
||||
[6] return
|
||||
to:@return
|
||||
|
||||
void main()
|
||||
main: scope:[main] from __start::@1
|
||||
[7] phi()
|
||||
[8] call cursor
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main
|
||||
[9] phi()
|
||||
[10] call bgcolor
|
||||
to:main::@6
|
||||
main::@6: scope:[main] from main::@5
|
||||
[11] phi()
|
||||
[12] call bordercolor
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main::@6
|
||||
[13] phi()
|
||||
[14] call textcolor
|
||||
to:main::@8
|
||||
main::@8: scope:[main] from main::@7
|
||||
[15] phi()
|
||||
[16] call cputsxy
|
||||
to:main::@9
|
||||
main::@9: scope:[main] from main::@8
|
||||
[17] phi()
|
||||
[18] call gotoxy
|
||||
to:main::@10
|
||||
main::@10: scope:[main] from main::@9
|
||||
[19] phi()
|
||||
[20] call revers
|
||||
to:main::@11
|
||||
main::@11: scope:[main] from main::@10
|
||||
[21] phi()
|
||||
[22] call cputs
|
||||
to:main::@12
|
||||
main::@12: scope:[main] from main::@11
|
||||
[23] phi()
|
||||
[24] call printf_string
|
||||
to:main::@13
|
||||
main::@13: scope:[main] from main::@12
|
||||
[25] phi()
|
||||
[26] call cputs
|
||||
to:main::@14
|
||||
main::@14: scope:[main] from main::@13
|
||||
[27] phi()
|
||||
[28] call waitkey
|
||||
to:main::@15
|
||||
main::@15: scope:[main] from main::@14
|
||||
[29] phi()
|
||||
[30] call clrscr
|
||||
to:main::@16
|
||||
main::@16: scope:[main] from main::@15
|
||||
[31] phi()
|
||||
[32] call revers
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main::@16 main::@19
|
||||
[33] main::i#2 = phi( main::@16/0, main::@19/main::i#1 )
|
||||
[34] call cputs
|
||||
to:main::@17
|
||||
main::@17: scope:[main] from main::@1
|
||||
[35] printf_sint::value#1 = main::i#2
|
||||
[36] call printf_sint
|
||||
to:main::@18
|
||||
main::@18: scope:[main] from main::@17
|
||||
[37] phi()
|
||||
[38] call cputs
|
||||
to:main::@19
|
||||
main::@19: scope:[main] from main::@18
|
||||
[39] main::i#1 = ++ main::i#2
|
||||
[40] if(main::i#1!=$33) goto main::@1
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@19
|
||||
[41] phi()
|
||||
[42] call waitkey
|
||||
to:main::@20
|
||||
main::@20: scope:[main] from main::@2
|
||||
[43] phi()
|
||||
[44] call scroll
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@20 main::@23
|
||||
[45] main::i1#2 = phi( main::@20/$33, main::@23/main::i1#1 )
|
||||
[46] call cputs
|
||||
to:main::@21
|
||||
main::@21: scope:[main] from main::@3
|
||||
[47] printf_sint::value#2 = main::i1#2
|
||||
[48] call printf_sint
|
||||
to:main::@22
|
||||
main::@22: scope:[main] from main::@21
|
||||
[49] phi()
|
||||
[50] call cputs
|
||||
to:main::@23
|
||||
main::@23: scope:[main] from main::@22
|
||||
[51] main::i1#1 = ++ main::i1#2
|
||||
[52] if(main::i1#1!=$c9) goto main::@3
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@23
|
||||
[53] phi()
|
||||
[54] call waitkey
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@4
|
||||
[55] return
|
||||
to:@return
|
||||
|
||||
byte cursor(byte cursor::onoff)
|
||||
cursor: scope:[cursor] from main
|
||||
[56] conio_display_cursor = cursor::onoff#0
|
||||
to:cursor::@return
|
||||
cursor::@return: scope:[cursor] from cursor
|
||||
[57] return
|
||||
to:@return
|
||||
|
||||
byte bgcolor(byte bgcolor::color)
|
||||
bgcolor: scope:[bgcolor] from main::@5
|
||||
[58] *COLOR2 = DARK_ORANGE
|
||||
to:bgcolor::@return
|
||||
bgcolor::@return: scope:[bgcolor] from bgcolor
|
||||
[59] return
|
||||
to:@return
|
||||
|
||||
byte bordercolor(byte bordercolor::color)
|
||||
bordercolor: scope:[bordercolor] from main::@6
|
||||
[60] *COLOR4 = MEDIUM_BLUE
|
||||
to:bordercolor::@return
|
||||
bordercolor::@return: scope:[bordercolor] from bordercolor
|
||||
[61] return
|
||||
to:@return
|
||||
|
||||
byte textcolor(byte textcolor::color)
|
||||
textcolor: scope:[textcolor] from main::@7
|
||||
[62] *COLOR1 = WHITE
|
||||
to:textcolor::@return
|
||||
textcolor::@return: scope:[textcolor] from textcolor
|
||||
[63] return
|
||||
to:@return
|
||||
|
||||
void cputsxy(byte cputsxy::x , byte cputsxy::y , to_nomodify byte* cputsxy::s)
|
||||
cputsxy: scope:[cputsxy] from main::@8
|
||||
[64] phi()
|
||||
[65] call gotoxy
|
||||
to:cputsxy::@1
|
||||
cputsxy::@1: scope:[cputsxy] from cputsxy
|
||||
[66] phi()
|
||||
[67] call cputs
|
||||
to:cputsxy::@return
|
||||
cputsxy::@return: scope:[cputsxy] from cputsxy::@1
|
||||
[68] return
|
||||
to:@return
|
||||
|
||||
void gotoxy(byte gotoxy::x , byte gotoxy::y)
|
||||
gotoxy: scope:[gotoxy] from clrscr::@1 cputsxy main::@9 newline::@3
|
||||
[69] gotoxy::y#4 = phi( clrscr::@1/0, cputsxy/cputsxy::y#0, main::@9/3, newline::@3/0 )
|
||||
[69] gotoxy::x#4 = phi( clrscr::@1/0, cputsxy/cputsxy::x#0, main::@9/0, newline::@3/0 )
|
||||
[70] *COLCRS = gotoxy::x#4
|
||||
[71] *ROWCRS = gotoxy::y#4
|
||||
[72] call setcursor
|
||||
to:gotoxy::@return
|
||||
gotoxy::@return: scope:[gotoxy] from gotoxy
|
||||
[73] return
|
||||
to:@return
|
||||
|
||||
byte revers(byte revers::onoff)
|
||||
revers: scope:[revers] from main::@10 main::@16
|
||||
[74] revers::onoff#2 = phi( main::@10/1, main::@16/0 )
|
||||
[75] if(revers::onoff#2==0) goto revers::@1
|
||||
to:revers::@2
|
||||
revers::@2: scope:[revers] from revers
|
||||
[76] conio_reverse_value = $80
|
||||
to:revers::@return
|
||||
revers::@return: scope:[revers] from revers::@1 revers::@2
|
||||
[77] return
|
||||
to:@return
|
||||
revers::@1: scope:[revers] from revers
|
||||
[78] conio_reverse_value = 0
|
||||
to:revers::@return
|
||||
|
||||
void cputs(to_nomodify byte* cputs::s)
|
||||
cputs: scope:[cputs] from cputsxy::@1 main::@1 main::@11 main::@13 main::@18 main::@22 main::@3 printf_number_buffer::@2 printf_string::@1
|
||||
[79] cputs::s#11 = phi( cputsxy::@1/main::s, main::@1/main::s3, main::@11/main::s1, main::@13/main::s2, main::@18/main::s4, main::@22/main::s4, main::@3/main::s5, printf_number_buffer::@2/printf_number_buffer::buffer_digits#0, printf_string::@1/main::name )
|
||||
to:cputs::@1
|
||||
cputs::@1: scope:[cputs] from cputs cputs::@2
|
||||
[80] cputs::s#10 = phi( cputs/cputs::s#11, cputs::@2/cputs::s#0 )
|
||||
[81] cputs::c#1 = *cputs::s#10
|
||||
[82] cputs::s#0 = ++ cputs::s#10
|
||||
[83] if(0!=cputs::c#1) goto cputs::@2
|
||||
to:cputs::@return
|
||||
cputs::@return: scope:[cputs] from cputs::@1
|
||||
[84] return
|
||||
to:@return
|
||||
cputs::@2: scope:[cputs] from cputs::@1
|
||||
[85] cputc::c = cputs::c#1
|
||||
[86] call cputc
|
||||
to:cputs::@1
|
||||
|
||||
void printf_string(byte* printf_string::str , byte printf_string::format_min_length , byte printf_string::format_justify_left)
|
||||
printf_string: scope:[printf_string] from main::@12
|
||||
[87] phi()
|
||||
to:printf_string::@1
|
||||
printf_string::@1: scope:[printf_string] from printf_string
|
||||
[88] phi()
|
||||
[89] call cputs
|
||||
to:printf_string::@return
|
||||
printf_string::@return: scope:[printf_string] from printf_string::@1
|
||||
[90] return
|
||||
to:@return
|
||||
|
||||
void waitkey()
|
||||
waitkey: scope:[waitkey] from main::@14 main::@2 main::@4
|
||||
[91] phi()
|
||||
to:waitkey::@1
|
||||
waitkey::@1: scope:[waitkey] from waitkey waitkey::@2
|
||||
[92] phi()
|
||||
[93] call kbhit
|
||||
[94] kbhit::return#3 = kbhit::return#2
|
||||
to:waitkey::@2
|
||||
waitkey::@2: scope:[waitkey] from waitkey::@1
|
||||
[95] waitkey::$1 = kbhit::return#3
|
||||
[96] if(0==waitkey::$1) goto waitkey::@1
|
||||
to:waitkey::clrkb1
|
||||
waitkey::clrkb1: scope:[waitkey] from waitkey::@2
|
||||
[97] *CH = $ff
|
||||
to:waitkey::@return
|
||||
waitkey::@return: scope:[waitkey] from waitkey::clrkb1
|
||||
[98] return
|
||||
to:@return
|
||||
|
||||
void clrscr()
|
||||
clrscr: scope:[clrscr] from main::@15
|
||||
[99] memset::str#7 = (void*)*SAVMSC
|
||||
[100] call memset
|
||||
to:clrscr::@1
|
||||
clrscr::@1: scope:[clrscr] from clrscr
|
||||
[101] *OLDCHR = 0
|
||||
[102] call gotoxy
|
||||
to:clrscr::@return
|
||||
clrscr::@return: scope:[clrscr] from clrscr::@1
|
||||
[103] return
|
||||
to:@return
|
||||
|
||||
void printf_sint(signed word printf_sint::value , byte printf_sint::format_min_length , byte printf_sint::format_justify_left , byte printf_sint::format_sign_always , byte printf_sint::format_zero_padding , byte printf_sint::format_upper_case , byte printf_sint::format_radix)
|
||||
printf_sint: scope:[printf_sint] from main::@17 main::@21
|
||||
[104] printf_sint::value#3 = phi( main::@17/printf_sint::value#1, main::@21/printf_sint::value#2 )
|
||||
[105] *((byte*)&printf_buffer) = 0
|
||||
[106] if(printf_sint::value#3<0) goto printf_sint::@1
|
||||
to:printf_sint::@2
|
||||
printf_sint::@1: scope:[printf_sint] from printf_sint
|
||||
[107] printf_sint::value#0 = - printf_sint::value#3
|
||||
[108] *((byte*)&printf_buffer) = '-'at
|
||||
to:printf_sint::@2
|
||||
printf_sint::@2: scope:[printf_sint] from printf_sint printf_sint::@1
|
||||
[109] printf_sint::value#5 = phi( printf_sint::@1/printf_sint::value#0, printf_sint/printf_sint::value#3 )
|
||||
[110] utoa::value#1 = (word)printf_sint::value#5
|
||||
[111] call utoa
|
||||
to:printf_sint::@3
|
||||
printf_sint::@3: scope:[printf_sint] from printf_sint::@2
|
||||
[112] printf_number_buffer::buffer_sign#0 = *((byte*)&printf_buffer)
|
||||
[113] call printf_number_buffer
|
||||
to:printf_sint::@return
|
||||
printf_sint::@return: scope:[printf_sint] from printf_sint::@3
|
||||
[114] return
|
||||
to:@return
|
||||
|
||||
byte scroll(byte scroll::onoff)
|
||||
scroll: scope:[scroll] from main::@20
|
||||
[115] conio_scroll_enable = scroll::onoff#0
|
||||
to:scroll::@return
|
||||
scroll::@return: scope:[scroll] from scroll
|
||||
[116] return
|
||||
to:@return
|
||||
|
||||
void setcursor()
|
||||
setcursor: scope:[setcursor] from cputc::@1 cputc::@4 gotoxy newline::@1 putchar::@1
|
||||
[117] *(*OLDADR) = *OLDCHR
|
||||
[118] call cursorLocation
|
||||
[119] cursorLocation::return#3 = cursorLocation::return#1
|
||||
to:setcursor::@4
|
||||
setcursor::@4: scope:[setcursor] from setcursor
|
||||
[120] setcursor::loc#0 = cursorLocation::return#3
|
||||
[121] setcursor::c#0 = *setcursor::loc#0
|
||||
[122] *OLDCHR = setcursor::c#0
|
||||
[123] *OLDADR = setcursor::loc#0
|
||||
[124] if(conio_display_cursor==0) goto setcursor::@1
|
||||
to:setcursor::@3
|
||||
setcursor::@3: scope:[setcursor] from setcursor::@4
|
||||
[125] *CRSINH = 0
|
||||
[126] setcursor::c#1 = setcursor::c#0 ^ $80
|
||||
to:setcursor::@2
|
||||
setcursor::@2: scope:[setcursor] from setcursor::@1 setcursor::@3
|
||||
[127] setcursor::c#3 = phi( setcursor::@1/setcursor::c#0, setcursor::@3/setcursor::c#1 )
|
||||
[128] *(*OLDADR) = setcursor::c#3
|
||||
to:setcursor::@return
|
||||
setcursor::@return: scope:[setcursor] from setcursor::@2
|
||||
[129] return
|
||||
to:@return
|
||||
setcursor::@1: scope:[setcursor] from setcursor::@4
|
||||
[130] *CRSINH = 1
|
||||
to:setcursor::@2
|
||||
|
||||
void cputc(volatile byte cputc::c)
|
||||
cputc: scope:[cputc] from cputs::@2 printf_number_buffer::@3
|
||||
[131] if(cputc::c=='
'at) goto cputc::@1
|
||||
to:cputc::@3
|
||||
cputc::@3: scope:[cputc] from cputc
|
||||
[132] if(cputc::c=='
|
||||
'at) goto cputc::@2
|
||||
to:cputc::@8
|
||||
cputc::@8: scope:[cputc] from cputc::@3
|
||||
[133] if(cputc::c==$9b) goto cputc::@2
|
||||
to:cputc::convertToScreenCode1
|
||||
cputc::convertToScreenCode1: scope:[cputc] from cputc::@8
|
||||
[134] cputc::convertToScreenCode1_return#0 = rawmap[*cputc::convertToScreenCode1_v#0]
|
||||
to:cputc::@6
|
||||
cputc::@6: scope:[cputc] from cputc::convertToScreenCode1
|
||||
[135] phi()
|
||||
[136] call putchar
|
||||
to:cputc::@7
|
||||
cputc::@7: scope:[cputc] from cputc::@6
|
||||
[137] *COLCRS = ++ *COLCRS
|
||||
[138] if(*COLCRS==$28) goto cputc::@5
|
||||
to:cputc::@4
|
||||
cputc::@4: scope:[cputc] from cputc::@7
|
||||
[139] phi()
|
||||
[140] call setcursor
|
||||
to:cputc::@return
|
||||
cputc::@return: scope:[cputc] from cputc::@1 cputc::@2 cputc::@4 cputc::@5
|
||||
[141] return
|
||||
to:@return
|
||||
cputc::@5: scope:[cputc] from cputc::@7
|
||||
[142] *COLCRS = 0
|
||||
[143] call newline
|
||||
to:cputc::@return
|
||||
cputc::@2: scope:[cputc] from cputc::@3 cputc::@8
|
||||
[144] *COLCRS = 0
|
||||
[145] call newline
|
||||
to:cputc::@return
|
||||
cputc::@1: scope:[cputc] from cputc
|
||||
[146] *COLCRS = 0
|
||||
[147] call setcursor
|
||||
to:cputc::@return
|
||||
|
||||
byte kbhit()
|
||||
kbhit: scope:[kbhit] from waitkey::@1
|
||||
[148] if(*CH==$ff) goto kbhit::@1
|
||||
to:kbhit::@return
|
||||
kbhit::@1: scope:[kbhit] from kbhit
|
||||
[149] phi()
|
||||
to:kbhit::@return
|
||||
kbhit::@return: scope:[kbhit] from kbhit kbhit::@1
|
||||
[150] kbhit::return#2 = phi( kbhit::@1/0, kbhit/1 )
|
||||
[151] return
|
||||
to:@return
|
||||
|
||||
void* memset(void* memset::str , byte memset::c , word memset::num)
|
||||
memset: scope:[memset] from clrscr newline::@7
|
||||
[152] memset::str#3 = phi( clrscr/memset::str#7, newline::@7/memset::str#8 )
|
||||
[152] memset::num#2 = phi( clrscr/(word)$28*$18, newline::@7/$28 )
|
||||
[153] if(memset::num#2<=0) goto memset::@return
|
||||
to:memset::@1
|
||||
memset::@1: scope:[memset] from memset
|
||||
[154] memset::end#0 = (byte*)memset::str#3 + memset::num#2
|
||||
[155] memset::dst#4 = (byte*)memset::str#3
|
||||
to:memset::@2
|
||||
memset::@2: scope:[memset] from memset::@1 memset::@3
|
||||
[156] memset::dst#2 = phi( memset::@1/memset::dst#4, memset::@3/memset::dst#1 )
|
||||
[157] if(memset::dst#2!=memset::end#0) goto memset::@3
|
||||
to:memset::@return
|
||||
memset::@return: scope:[memset] from memset memset::@2
|
||||
[158] return
|
||||
to:@return
|
||||
memset::@3: scope:[memset] from memset::@2
|
||||
[159] *memset::dst#2 = 0
|
||||
[160] memset::dst#1 = ++ memset::dst#2
|
||||
to:memset::@2
|
||||
|
||||
void utoa(word utoa::value , byte* utoa::buffer , byte utoa::radix)
|
||||
utoa: scope:[utoa] from printf_sint::@2
|
||||
[161] phi()
|
||||
to:utoa::@1
|
||||
utoa::@1: scope:[utoa] from utoa utoa::@4
|
||||
[162] utoa::buffer#11 = phi( utoa::@4/utoa::buffer#14, utoa/(byte*)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS )
|
||||
[162] utoa::started#2 = phi( utoa::@4/utoa::started#4, utoa/0 )
|
||||
[162] utoa::value#2 = phi( utoa::@4/utoa::value#6, utoa/utoa::value#1 )
|
||||
[162] utoa::digit#2 = phi( utoa::@4/utoa::digit#1, utoa/0 )
|
||||
[163] if(utoa::digit#2<5-1) goto utoa::@2
|
||||
to:utoa::@3
|
||||
utoa::@3: scope:[utoa] from utoa::@1
|
||||
[164] utoa::$11 = (byte)utoa::value#2
|
||||
[165] *utoa::buffer#11 = DIGITS[utoa::$11]
|
||||
[166] utoa::buffer#3 = ++ utoa::buffer#11
|
||||
[167] *utoa::buffer#3 = 0
|
||||
to:utoa::@return
|
||||
utoa::@return: scope:[utoa] from utoa::@3
|
||||
[168] return
|
||||
to:@return
|
||||
utoa::@2: scope:[utoa] from utoa::@1
|
||||
[169] utoa::$10 = utoa::digit#2 << 1
|
||||
[170] utoa::digit_value#0 = RADIX_DECIMAL_VALUES[utoa::$10]
|
||||
[171] if(0!=utoa::started#2) goto utoa::@5
|
||||
to:utoa::@7
|
||||
utoa::@7: scope:[utoa] from utoa::@2
|
||||
[172] if(utoa::value#2>=utoa::digit_value#0) goto utoa::@5
|
||||
to:utoa::@4
|
||||
utoa::@4: scope:[utoa] from utoa::@6 utoa::@7
|
||||
[173] utoa::buffer#14 = phi( utoa::@7/utoa::buffer#11, utoa::@6/utoa::buffer#4 )
|
||||
[173] utoa::started#4 = phi( utoa::@7/utoa::started#2, utoa::@6/1 )
|
||||
[173] utoa::value#6 = phi( utoa::@7/utoa::value#2, utoa::@6/utoa::value#0 )
|
||||
[174] utoa::digit#1 = ++ utoa::digit#2
|
||||
to:utoa::@1
|
||||
utoa::@5: scope:[utoa] from utoa::@2 utoa::@7
|
||||
[175] utoa_append::buffer#0 = utoa::buffer#11
|
||||
[176] utoa_append::value#0 = utoa::value#2
|
||||
[177] utoa_append::sub#0 = utoa::digit_value#0
|
||||
[178] call utoa_append
|
||||
[179] utoa_append::return#0 = utoa_append::value#2
|
||||
to:utoa::@6
|
||||
utoa::@6: scope:[utoa] from utoa::@5
|
||||
[180] utoa::value#0 = utoa_append::return#0
|
||||
[181] utoa::buffer#4 = ++ utoa::buffer#11
|
||||
to:utoa::@4
|
||||
|
||||
void printf_number_buffer(byte printf_number_buffer::buffer_sign , byte* printf_number_buffer::buffer_digits , byte printf_number_buffer::format_min_length , byte printf_number_buffer::format_justify_left , byte printf_number_buffer::format_sign_always , byte printf_number_buffer::format_zero_padding , byte printf_number_buffer::format_upper_case , byte printf_number_buffer::format_radix)
|
||||
printf_number_buffer: scope:[printf_number_buffer] from printf_sint::@3
|
||||
[182] phi()
|
||||
to:printf_number_buffer::@1
|
||||
printf_number_buffer::@1: scope:[printf_number_buffer] from printf_number_buffer
|
||||
[183] if(0==printf_number_buffer::buffer_sign#0) goto printf_number_buffer::@2
|
||||
to:printf_number_buffer::@3
|
||||
printf_number_buffer::@3: scope:[printf_number_buffer] from printf_number_buffer::@1
|
||||
[184] cputc::c = printf_number_buffer::buffer_sign#0
|
||||
[185] call cputc
|
||||
to:printf_number_buffer::@2
|
||||
printf_number_buffer::@2: scope:[printf_number_buffer] from printf_number_buffer::@1 printf_number_buffer::@3
|
||||
[186] phi()
|
||||
[187] call cputs
|
||||
to:printf_number_buffer::@return
|
||||
printf_number_buffer::@return: scope:[printf_number_buffer] from printf_number_buffer::@2
|
||||
[188] return
|
||||
to:@return
|
||||
|
||||
byte* cursorLocation()
|
||||
cursorLocation: scope:[cursorLocation] from putchar setcursor
|
||||
[189] cursorLocation::$3 = (word)*ROWCRS
|
||||
[190] cursorLocation::$4 = cursorLocation::$3 << 2
|
||||
[191] cursorLocation::$5 = cursorLocation::$4 + cursorLocation::$3
|
||||
[192] cursorLocation::$0 = cursorLocation::$5 << 3
|
||||
[193] cursorLocation::$1 = *SAVMSC + cursorLocation::$0
|
||||
[194] cursorLocation::return#1 = cursorLocation::$1 + *COLCRS
|
||||
to:cursorLocation::@return
|
||||
cursorLocation::@return: scope:[cursorLocation] from cursorLocation
|
||||
[195] return
|
||||
to:@return
|
||||
|
||||
void putchar(byte putchar::code)
|
||||
putchar: scope:[putchar] from cputc::@6
|
||||
[196] *(*OLDADR) = *OLDCHR
|
||||
[197] call cursorLocation
|
||||
[198] cursorLocation::return#0 = cursorLocation::return#1
|
||||
to:putchar::@1
|
||||
putchar::@1: scope:[putchar] from putchar
|
||||
[199] putchar::loc#0 = cursorLocation::return#0
|
||||
[200] putchar::newChar#0 = cputc::convertToScreenCode1_return#0 | conio_reverse_value
|
||||
[201] *putchar::loc#0 = putchar::newChar#0
|
||||
[202] *OLDCHR = putchar::newChar#0
|
||||
[203] call setcursor
|
||||
to:putchar::@return
|
||||
putchar::@return: scope:[putchar] from putchar::@1
|
||||
[204] return
|
||||
to:@return
|
||||
|
||||
void newline()
|
||||
newline: scope:[newline] from cputc::@2 cputc::@5
|
||||
[205] *ROWCRS = ++ *ROWCRS
|
||||
[206] if(*ROWCRS!=$18) goto newline::@1
|
||||
to:newline::@2
|
||||
newline::@2: scope:[newline] from newline
|
||||
[207] if(conio_scroll_enable==1) goto newline::@4
|
||||
to:newline::@3
|
||||
newline::@3: scope:[newline] from newline::@2
|
||||
[208] phi()
|
||||
[209] call gotoxy
|
||||
to:newline::@1
|
||||
newline::@1: scope:[newline] from newline newline::@3 newline::@8
|
||||
[210] phi()
|
||||
[211] call setcursor
|
||||
to:newline::@return
|
||||
newline::@return: scope:[newline] from newline::@1
|
||||
[212] return
|
||||
to:@return
|
||||
newline::@4: scope:[newline] from newline::@2
|
||||
[213] if(conio_display_cursor!=1) goto newline::@5
|
||||
to:newline::@6
|
||||
newline::@6: scope:[newline] from newline::@4
|
||||
[214] *(*OLDADR) = *(*OLDADR) ^ $80
|
||||
to:newline::@5
|
||||
newline::@5: scope:[newline] from newline::@4 newline::@6
|
||||
[215] newline::start#0 = *SAVMSC
|
||||
[216] memcpy::source#0 = newline::start#0 + $28
|
||||
[217] memcpy::destination#0 = (void*)newline::start#0
|
||||
[218] call memcpy
|
||||
to:newline::@7
|
||||
newline::@7: scope:[newline] from newline::@5
|
||||
[219] memset::str#0 = newline::start#0 + (word)$28*$17
|
||||
[220] memset::str#8 = (void*)memset::str#0
|
||||
[221] call memset
|
||||
to:newline::@8
|
||||
newline::@8: scope:[newline] from newline::@7
|
||||
[222] *ROWCRS = (byte)$18-1
|
||||
to:newline::@1
|
||||
|
||||
word utoa_append(byte* utoa_append::buffer , word utoa_append::value , word utoa_append::sub)
|
||||
utoa_append: scope:[utoa_append] from utoa::@5
|
||||
[223] phi()
|
||||
to:utoa_append::@1
|
||||
utoa_append::@1: scope:[utoa_append] from utoa_append utoa_append::@2
|
||||
[224] utoa_append::digit#2 = phi( utoa_append/0, utoa_append::@2/utoa_append::digit#1 )
|
||||
[224] utoa_append::value#2 = phi( utoa_append/utoa_append::value#0, utoa_append::@2/utoa_append::value#1 )
|
||||
[225] if(utoa_append::value#2>=utoa_append::sub#0) goto utoa_append::@2
|
||||
to:utoa_append::@3
|
||||
utoa_append::@3: scope:[utoa_append] from utoa_append::@1
|
||||
[226] *utoa_append::buffer#0 = DIGITS[utoa_append::digit#2]
|
||||
to:utoa_append::@return
|
||||
utoa_append::@return: scope:[utoa_append] from utoa_append::@3
|
||||
[227] return
|
||||
to:@return
|
||||
utoa_append::@2: scope:[utoa_append] from utoa_append::@1
|
||||
[228] utoa_append::digit#1 = ++ utoa_append::digit#2
|
||||
[229] utoa_append::value#1 = utoa_append::value#2 - utoa_append::sub#0
|
||||
to:utoa_append::@1
|
||||
|
||||
void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num)
|
||||
memcpy: scope:[memcpy] from newline::@5
|
||||
[230] memcpy::src_end#0 = (byte*)(void*)memcpy::source#0 + memcpy::num#0
|
||||
[231] memcpy::src#4 = (byte*)(void*)memcpy::source#0
|
||||
[232] memcpy::dst#4 = (byte*)memcpy::destination#0
|
||||
to:memcpy::@1
|
||||
memcpy::@1: scope:[memcpy] from memcpy memcpy::@2
|
||||
[233] memcpy::dst#2 = phi( memcpy/memcpy::dst#4, memcpy::@2/memcpy::dst#1 )
|
||||
[233] memcpy::src#2 = phi( memcpy/memcpy::src#4, memcpy::@2/memcpy::src#1 )
|
||||
[234] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2
|
||||
to:memcpy::@return
|
||||
memcpy::@return: scope:[memcpy] from memcpy::@1
|
||||
[235] return
|
||||
to:@return
|
||||
memcpy::@2: scope:[memcpy] from memcpy::@1
|
||||
[236] *memcpy::dst#2 = *memcpy::src#2
|
||||
[237] memcpy::dst#1 = ++ memcpy::dst#2
|
||||
[238] memcpy::src#1 = ++ memcpy::src#2
|
||||
to:memcpy::@1
|
8325
src/test/ref/examples/atarixl/conio-test.log
Normal file
8325
src/test/ref/examples/atarixl/conio-test.log
Normal file
File diff suppressed because one or more lines are too long
272
src/test/ref/examples/atarixl/conio-test.sym
Normal file
272
src/test/ref/examples/atarixl/conio-test.sym
Normal file
@ -0,0 +1,272 @@
|
||||
const nomodify byte* CH = (byte*) 764
|
||||
const word* COLCRS = (word*) 85
|
||||
const nomodify byte* COLOR1 = (byte*) 709
|
||||
const nomodify byte* COLOR2 = (byte*) 710
|
||||
const nomodify byte* COLOR4 = (byte*) 712
|
||||
const nomodify byte* CRSINH = (byte*) 752
|
||||
const nomodify byte DARK_ORANGE = $30
|
||||
const byte* DIGITS[] = "0123456789abcdef"atz
|
||||
const nomodify byte MEDIUM_BLUE = $80
|
||||
const byte OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS = 1
|
||||
const nomodify byte** OLDADR = (byte**) 94
|
||||
const nomodify byte* OLDCHR = (byte*) 93
|
||||
const byte RADIX::BINARY = 2
|
||||
const byte RADIX::DECIMAL = $a
|
||||
const byte RADIX::HEXADECIMAL = $10
|
||||
const byte RADIX::OCTAL = 8
|
||||
const word* RADIX_DECIMAL_VALUES[] = { $2710, $3e8, $64, $a }
|
||||
const byte* ROWCRS = (byte*) 84
|
||||
const nomodify byte** SAVMSC = (byte**) 88
|
||||
const byte SIZEOF_STRUCT_PRINTF_BUFFER_NUMBER = $c
|
||||
const nomodify byte WHITE = $fe
|
||||
void __start()
|
||||
byte bgcolor(byte bgcolor::color)
|
||||
byte bgcolor::color
|
||||
byte bgcolor::old
|
||||
byte bgcolor::return
|
||||
byte bordercolor(byte bordercolor::color)
|
||||
byte bordercolor::color
|
||||
byte bordercolor::old
|
||||
byte bordercolor::return
|
||||
void clrscr()
|
||||
byte conio_display_cursor loadstore zp[1]:136 6.733333340333332E8
|
||||
byte conio_reverse_value loadstore zp[1]:135 9803923.578431373
|
||||
byte conio_scroll_enable loadstore zp[1]:137 8547009.435897436
|
||||
void cputc(volatile byte cputc::c)
|
||||
volatile byte cputc::c loadstore zp[1]:138 7.750250125E7
|
||||
byte cputc::convertToScreenCode1_return
|
||||
byte cputc::convertToScreenCode1_return#0 reg byte x 1.833333336666667E8
|
||||
byte* cputc::convertToScreenCode1_v
|
||||
const byte* cputc::convertToScreenCode1_v#0 convertToScreenCode1_v = &cputc::c
|
||||
void cputs(to_nomodify byte* cputs::s)
|
||||
byte cputs::c
|
||||
byte cputs::c#1 reg byte a 1.0000001E7
|
||||
to_nomodify byte* cputs::s
|
||||
to_nomodify byte* cputs::s#0 s zp[2]:132 5000000.5
|
||||
to_nomodify byte* cputs::s#10 s zp[2]:132 1.5050002E7
|
||||
to_nomodify byte* cputs::s#11 s zp[2]:132 100001.0
|
||||
void cputsxy(byte cputsxy::x , byte cputsxy::y , to_nomodify byte* cputsxy::s)
|
||||
to_nomodify byte* cputsxy::s
|
||||
byte cputsxy::x
|
||||
const byte cputsxy::x#0 x = 0
|
||||
byte cputsxy::y
|
||||
const byte cputsxy::y#0 y = 1
|
||||
byte cursor(byte cursor::onoff)
|
||||
byte cursor::oldValue
|
||||
byte cursor::onoff
|
||||
const byte cursor::onoff#0 onoff = 0
|
||||
byte cursor::return
|
||||
byte* cursorLocation()
|
||||
word~ cursorLocation::$0 zp[2]:139 2.000000000002E12
|
||||
byte*~ cursorLocation::$1 zp[2]:139 2.000000000002E12
|
||||
word~ cursorLocation::$3 zp[2]:139 1.5000000000015E12
|
||||
word~ cursorLocation::$4 zp[2]:143 2.000000000002E12
|
||||
word~ cursorLocation::$5 zp[2]:139 2.000000000002E12
|
||||
byte* cursorLocation::return
|
||||
byte* cursorLocation::return#0 return zp[2]:139 2.000000002E9
|
||||
byte* cursorLocation::return#1 return zp[2]:139 2.7525000000075E11
|
||||
byte* cursorLocation::return#3 return zp[2]:139 2.00000000002E11
|
||||
void gotoxy(byte gotoxy::x , byte gotoxy::y)
|
||||
byte gotoxy::x
|
||||
byte gotoxy::x#4 reg byte a 1.0000000001E10
|
||||
byte gotoxy::y
|
||||
byte gotoxy::y#4 reg byte x 5.0000000005E9
|
||||
byte kbhit()
|
||||
byte kbhit::return
|
||||
byte kbhit::return#2 reg byte a 333.6666666666667
|
||||
byte kbhit::return#3 reg byte a 2002.0
|
||||
void main()
|
||||
signed word main::i
|
||||
signed word main::i#1 i zp[2]:128 151.5
|
||||
signed word main::i#2 i zp[2]:128 50.5
|
||||
signed word main::i1
|
||||
signed word main::i1#1 i1 zp[2]:130 151.5
|
||||
signed word main::i1#2 i1 zp[2]:130 50.5
|
||||
const byte* main::name = "Mark"at
|
||||
const byte* main::s[$f] = "Hello, World!
|
||||
"at
|
||||
const byte* main::s1[8] = "Hello, "at
|
||||
const byte* main::s2[$11] = " - press a key!
|
||||
"at
|
||||
const byte* main::s3[$15] = "Scrolling lines ... "at
|
||||
const byte* main::s4[2] = "
|
||||
"at
|
||||
const byte* main::s5[$19] = "Some wrapping lines ... "at
|
||||
void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num)
|
||||
void* memcpy::destination
|
||||
void* memcpy::destination#0 destination zp[2]:143 3.333333336666667E8
|
||||
byte* memcpy::dst
|
||||
byte* memcpy::dst#1 dst zp[2]:143 1.0000000000001E13
|
||||
byte* memcpy::dst#2 dst zp[2]:143 1.0003333333334666E13
|
||||
byte* memcpy::dst#4 dst zp[2]:143 2.0000000002E10
|
||||
word memcpy::num
|
||||
const word memcpy::num#0 num = (word)$28*$17
|
||||
void* memcpy::return
|
||||
void* memcpy::source
|
||||
byte* memcpy::source#0 source zp[2]:139 3.333333336666667E8
|
||||
byte* memcpy::src
|
||||
byte* memcpy::src#1 src zp[2]:139 2.0000000000002E13
|
||||
byte* memcpy::src#2 src zp[2]:139 1.000250000000125E13
|
||||
byte* memcpy::src#4 src zp[2]:139 1.0000000001E10
|
||||
byte* memcpy::src_end
|
||||
byte* memcpy::src_end#0 src_end zp[2]:145 1.25125000000025E12
|
||||
void* memset(void* memset::str , byte memset::c , word memset::num)
|
||||
byte memset::c
|
||||
byte* memset::dst
|
||||
byte* memset::dst#1 dst zp[2]:141 2.0000000000002E13
|
||||
byte* memset::dst#2 dst zp[2]:141 1.3336666666668332E13
|
||||
byte* memset::dst#4 dst zp[2]:141 2.0000000002E10
|
||||
byte* memset::end
|
||||
byte* memset::end#0 end zp[2]:139 1.6683333333336665E12
|
||||
word memset::num
|
||||
word memset::num#2 num zp[2]:139 1.0000000001E10
|
||||
void* memset::return
|
||||
void* memset::str
|
||||
byte* memset::str#0 str zp[2]:141 1.000000001E9
|
||||
void* memset::str#3 str zp[2]:141 3.333333673333334E8
|
||||
void* memset::str#7 str zp[2]:141 202.0
|
||||
void* memset::str#8 str zp[2]:141 2.000000002E9
|
||||
void newline()
|
||||
byte* newline::start
|
||||
byte* newline::start#0 start zp[2]:141 7.5000000075E8
|
||||
struct printf_buffer_number printf_buffer loadstore mem[12] = {}
|
||||
void printf_number_buffer(byte printf_number_buffer::buffer_sign , byte* printf_number_buffer::buffer_digits , byte printf_number_buffer::format_min_length , byte printf_number_buffer::format_justify_left , byte printf_number_buffer::format_sign_always , byte printf_number_buffer::format_zero_padding , byte printf_number_buffer::format_upper_case , byte printf_number_buffer::format_radix)
|
||||
struct printf_buffer_number printf_number_buffer::buffer
|
||||
byte* printf_number_buffer::buffer_digits
|
||||
const byte* printf_number_buffer::buffer_digits#0 buffer_digits = (byte*)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS
|
||||
byte printf_number_buffer::buffer_sign
|
||||
byte printf_number_buffer::buffer_sign#0 reg byte a 7001.0
|
||||
struct printf_format_number printf_number_buffer::format
|
||||
byte printf_number_buffer::format_justify_left
|
||||
byte printf_number_buffer::format_min_length
|
||||
byte printf_number_buffer::format_radix
|
||||
byte printf_number_buffer::format_sign_always
|
||||
byte printf_number_buffer::format_upper_case
|
||||
byte printf_number_buffer::format_zero_padding
|
||||
signed byte printf_number_buffer::len
|
||||
signed byte printf_number_buffer::padding
|
||||
void printf_sint(signed word printf_sint::value , byte printf_sint::format_min_length , byte printf_sint::format_justify_left , byte printf_sint::format_sign_always , byte printf_sint::format_zero_padding , byte printf_sint::format_upper_case , byte printf_sint::format_radix)
|
||||
struct printf_format_number printf_sint::format
|
||||
byte printf_sint::format_justify_left
|
||||
byte printf_sint::format_min_length
|
||||
byte printf_sint::format_radix
|
||||
byte printf_sint::format_sign_always
|
||||
byte printf_sint::format_upper_case
|
||||
byte printf_sint::format_zero_padding
|
||||
word printf_sint::uvalue
|
||||
signed word printf_sint::value
|
||||
signed word printf_sint::value#0 value zp[2]:132 1001.0
|
||||
signed word printf_sint::value#1 value zp[2]:132 202.0
|
||||
signed word printf_sint::value#2 value zp[2]:132 202.0
|
||||
signed word printf_sint::value#3 value zp[2]:132 1068.3333333333335
|
||||
signed word printf_sint::value#5 value zp[2]:132 2002.0
|
||||
void printf_string(byte* printf_string::str , byte printf_string::format_min_length , byte printf_string::format_justify_left)
|
||||
struct printf_format_string printf_string::format
|
||||
byte printf_string::format_justify_left
|
||||
byte printf_string::format_min_length
|
||||
signed byte printf_string::len
|
||||
signed byte printf_string::padding
|
||||
byte* printf_string::str
|
||||
void putchar(byte putchar::code)
|
||||
byte putchar::code
|
||||
byte* putchar::loc
|
||||
byte* putchar::loc#0 loc zp[2]:139 1.000000001E9
|
||||
byte putchar::newChar
|
||||
byte putchar::newChar#0 reg byte a 1.5000000015E9
|
||||
const byte* rawmap[$100] = kickasm {{ .var ht = Hashtable().put(0,64, 1,0, 2,32, 3,96) // the table for converting bit 6,7 into ora value
|
||||
.for(var i=0; i<256; i++) {
|
||||
.var idx = (i & $60) / 32
|
||||
.var mask = i & $9f
|
||||
.byte mask | ht.get(idx)
|
||||
}
|
||||
}}
|
||||
byte revers(byte revers::onoff)
|
||||
byte revers::old
|
||||
byte revers::onoff
|
||||
byte revers::onoff#2 reg byte a 101.0
|
||||
byte revers::return
|
||||
byte scroll(byte scroll::onoff)
|
||||
byte scroll::old
|
||||
byte scroll::onoff
|
||||
const byte scroll::onoff#0 onoff = 0
|
||||
byte scroll::return
|
||||
void setcursor()
|
||||
byte setcursor::c
|
||||
byte setcursor::c#0 reg byte x 6.6666666667333336E10
|
||||
byte setcursor::c#1 reg byte x 2.00000000002E11
|
||||
byte setcursor::c#3 reg byte x 3.00000000003E11
|
||||
byte* setcursor::loc
|
||||
byte* setcursor::loc#0 loc zp[2]:139 1.00000000001E11
|
||||
byte textcolor(byte textcolor::color)
|
||||
byte textcolor::color
|
||||
byte textcolor::old
|
||||
byte textcolor::return
|
||||
void utoa(word utoa::value , byte* utoa::buffer , byte utoa::radix)
|
||||
byte~ utoa::$10 reg byte a 2000002.0
|
||||
byte~ utoa::$11 reg byte a 20002.0
|
||||
byte* utoa::buffer
|
||||
byte* utoa::buffer#11 buffer zp[2]:139 287143.2857142857
|
||||
byte* utoa::buffer#14 buffer zp[2]:139 1500001.5
|
||||
byte* utoa::buffer#3 buffer zp[2]:139 20002.0
|
||||
byte* utoa::buffer#4 buffer zp[2]:139 2000002.0
|
||||
byte utoa::digit
|
||||
byte utoa::digit#1 digit zp[1]:134 2000002.0
|
||||
byte utoa::digit#2 digit zp[1]:134 285714.5714285714
|
||||
word utoa::digit_value
|
||||
word utoa::digit_value#0 digit_value zp[2]:141 600000.6000000001
|
||||
word* utoa::digit_values
|
||||
byte utoa::max_digits
|
||||
byte utoa::radix
|
||||
byte utoa::started
|
||||
byte utoa::started#2 reg byte x 500000.5
|
||||
byte utoa::started#4 reg byte x 1000001.0
|
||||
word utoa::value
|
||||
word utoa::value#0 value zp[2]:132 1000001.0
|
||||
word utoa::value#1 value zp[2]:132 5501.0
|
||||
word utoa::value#2 value zp[2]:132 572857.857142857
|
||||
word utoa::value#6 value zp[2]:132 1500001.5
|
||||
word utoa_append(byte* utoa_append::buffer , word utoa_append::value , word utoa_append::sub)
|
||||
byte* utoa_append::buffer
|
||||
byte* utoa_append::buffer#0 buffer zp[2]:139 1375000.25
|
||||
byte utoa_append::digit
|
||||
byte utoa_append::digit#1 reg byte x 1.0000000001E10
|
||||
byte utoa_append::digit#2 reg byte x 1.00050000015E10
|
||||
word utoa_append::return
|
||||
word utoa_append::return#0 return zp[2]:132 2000002.0
|
||||
word utoa_append::sub
|
||||
word utoa_append::sub#0 sub zp[2]:141 3.3335000005E9
|
||||
word utoa_append::value
|
||||
word utoa_append::value#0 value zp[2]:132 3666667.333333333
|
||||
word utoa_append::value#1 value zp[2]:132 2.0000000002E10
|
||||
word utoa_append::value#2 value zp[2]:132 5.001833334166666E9
|
||||
void waitkey()
|
||||
byte~ waitkey::$1 reg byte a 2002.0
|
||||
|
||||
zp[2]:128 [ main::i#2 main::i#1 ]
|
||||
zp[2]:130 [ main::i1#2 main::i1#1 ]
|
||||
reg byte a [ gotoxy::x#4 ]
|
||||
reg byte x [ gotoxy::y#4 ]
|
||||
reg byte a [ revers::onoff#2 ]
|
||||
zp[2]:132 [ printf_sint::value#5 printf_sint::value#0 printf_sint::value#3 printf_sint::value#1 printf_sint::value#2 utoa::value#2 utoa::value#6 utoa::value#1 utoa::value#0 utoa_append::value#2 utoa_append::value#0 utoa_append::value#1 utoa_append::return#0 cputs::s#10 cputs::s#11 cputs::s#0 ]
|
||||
reg byte x [ setcursor::c#3 setcursor::c#0 setcursor::c#1 ]
|
||||
reg byte a [ kbhit::return#2 ]
|
||||
zp[1]:134 [ utoa::digit#2 utoa::digit#1 ]
|
||||
reg byte x [ utoa::started#2 utoa::started#4 ]
|
||||
reg byte x [ utoa_append::digit#2 utoa_append::digit#1 ]
|
||||
zp[1]:135 [ conio_reverse_value ]
|
||||
zp[1]:136 [ conio_display_cursor ]
|
||||
zp[1]:137 [ conio_scroll_enable ]
|
||||
reg byte a [ cputs::c#1 ]
|
||||
zp[1]:138 [ cputc::c ]
|
||||
reg byte a [ kbhit::return#3 ]
|
||||
reg byte a [ waitkey::$1 ]
|
||||
reg byte a [ printf_number_buffer::buffer_sign#0 ]
|
||||
zp[2]:139 [ cursorLocation::return#3 setcursor::loc#0 cursorLocation::return#1 cursorLocation::$0 cursorLocation::$1 cursorLocation::return#0 putchar::loc#0 cursorLocation::$3 cursorLocation::$5 memcpy::src#2 memcpy::src#4 memcpy::src#1 memcpy::source#0 utoa::buffer#11 utoa::buffer#14 utoa::buffer#4 utoa::buffer#3 utoa_append::buffer#0 memset::num#2 memset::end#0 ]
|
||||
reg byte x [ cputc::convertToScreenCode1_return#0 ]
|
||||
reg byte a [ utoa::$11 ]
|
||||
reg byte a [ utoa::$10 ]
|
||||
zp[2]:141 [ utoa::digit_value#0 utoa_append::sub#0 memset::str#3 memset::str#7 memset::str#8 memset::dst#2 memset::dst#4 memset::dst#1 memset::str#0 newline::start#0 ]
|
||||
zp[2]:143 [ cursorLocation::$4 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 memcpy::destination#0 ]
|
||||
reg byte a [ putchar::newChar#0 ]
|
||||
zp[2]:145 [ memcpy::src_end#0 ]
|
||||
mem[12] [ printf_buffer ]
|
@ -37,6 +37,7 @@ ProgramEnd:
|
||||
.const BLANK4 = $30
|
||||
// Blank 8 lines
|
||||
.const BLANK8 = $70
|
||||
// Atari OS Shadow registers
|
||||
// OS Shadow ANTIC Direct Memory Access Control ($D400)
|
||||
.label SDMCTL = $22f
|
||||
// OS Shadow ANTIC Display List Pointer ($D402)
|
||||
|
@ -162,6 +162,7 @@ ProgramEnd:
|
||||
.const BLANK4 = $30
|
||||
// Blank 8 lines
|
||||
.const BLANK8 = $70
|
||||
// Atari OS Shadow registers
|
||||
// OS Shadow ANTIC Direct Memory Access Control ($D400)
|
||||
.label SDMCTL = $22f
|
||||
// OS Shadow ANTIC Display List Pointer ($D402)
|
||||
@ -268,6 +269,7 @@ ProgramEnd:
|
||||
.const BLANK4 = $30
|
||||
// Blank 8 lines
|
||||
.const BLANK8 = $70
|
||||
// Atari OS Shadow registers
|
||||
// OS Shadow ANTIC Direct Memory Access Control ($D400)
|
||||
.label SDMCTL = $22f
|
||||
// OS Shadow ANTIC Display List Pointer ($D402)
|
||||
|
@ -355,7 +355,7 @@ clrscr: {
|
||||
jmp __b3
|
||||
}
|
||||
// If onoff is 1, scrolling is enabled when outputting past the end of the screen
|
||||
// If onoff is 1, scrolling is disabled and the cursor instead moves to (0,0)
|
||||
// If onoff is 0, scrolling is disabled and the cursor instead moves to (0,0)
|
||||
// The function returns the old scroll setting.
|
||||
scroll: {
|
||||
.const onoff = 0
|
||||
|
@ -3735,7 +3735,7 @@ clrscr: {
|
||||
}
|
||||
// scroll
|
||||
// If onoff is 1, scrolling is enabled when outputting past the end of the screen
|
||||
// If onoff is 1, scrolling is disabled and the cursor instead moves to (0,0)
|
||||
// If onoff is 0, scrolling is disabled and the cursor instead moves to (0,0)
|
||||
// The function returns the old scroll setting.
|
||||
scroll: {
|
||||
.const onoff = 0
|
||||
@ -5558,7 +5558,7 @@ clrscr: {
|
||||
}
|
||||
// scroll
|
||||
// If onoff is 1, scrolling is enabled when outputting past the end of the screen
|
||||
// If onoff is 1, scrolling is disabled and the cursor instead moves to (0,0)
|
||||
// If onoff is 0, scrolling is disabled and the cursor instead moves to (0,0)
|
||||
// The function returns the old scroll setting.
|
||||
scroll: {
|
||||
.const onoff = 0
|
||||
|
Loading…
x
Reference in New Issue
Block a user