Apple2: Make 80-columns support dynamic on apple2 target

Add a machinetype identifier to help us quickly identify
Apple //e (bit 7) and //e enhanced (bit 6).

Use it in conio functions for 80-columns code instead of
relying entirely on the __APPLE2ENH__ target.

Move videomode() to the apple2 target, and have it return
an error if 80-columns hardware is not available - this
is a lie for now, it is considered available on //e enhanced,
which may not be true, and not available on //e, which
may also be not true. An ulterior patch will make that
check correctly.

Adapt the box/line drawing characters so that one can use
MouseText on the apple2 target if it is available, by
defining DYN_DRAW_BOX. No change by default: MouseText is
considered available on apple2enh and not available on
apple2.
This commit is contained in:
Colin Leroy-Mira
2025-05-27 16:31:23 +02:00
committed by Oliver Schmidt
parent cd92e4f0af
commit 816666615b
23 changed files with 523 additions and 107 deletions

View File

@@ -361,6 +361,7 @@ usage.
<item>rebootafterexit <item>rebootafterexit
<item>ser_apple2_slot <item>ser_apple2_slot
<item>tgi_apple2_mix <item>tgi_apple2_mix
<item>videomode
</itemize> </itemize>
@@ -406,6 +407,10 @@ The names in the parentheses denote the symbols to be used for static linking of
with <tt/-S $4000/ to reserve the first hires page or with <tt/-S $6000/ with <tt/-S $4000/ to reserve the first hires page or with <tt/-S $6000/
to reserve both hires pages. to reserve both hires pages.
Note that the second hires page is only available if the text display is not in
80 column mode. This can be asserted by calling <tt/videomode (VIDEOMODE_40COL);/
before installing the driver.
The function <tt/tgi_apple2_mix()/ allows to activate 4 lines of text. The The function <tt/tgi_apple2_mix()/ allows to activate 4 lines of text. The
function doesn't clear the corresponding area at the bottom of the screen. function doesn't clear the corresponding area at the bottom of the screen.

View File

@@ -103,6 +103,7 @@ function.
<item><ref id="gmtime_dt" name="gmtime_dt"> <item><ref id="gmtime_dt" name="gmtime_dt">
<item><ref id="mktime_dt" name="mktime_dt"> <item><ref id="mktime_dt" name="mktime_dt">
<item>rebootafterexit <item>rebootafterexit
<item><ref id="videomode" name="videomode">
</itemize> </itemize>
@@ -8477,24 +8478,27 @@ used in presence of a prototype.
<tag/Function/Switch to either 40- or 80-column text mode, or a standard <tag/Function/Switch to either 40- or 80-column text mode, or a standard
graphics mode. graphics mode.
<tag/Header/<tt/ <tag/Header/<tt/
<ref id="apple2.h" name="apple2.h">,
<ref id="apple2enh.h" name="apple2enh.h">, <ref id="apple2enh.h" name="apple2enh.h">,
<ref id="c128.h" name="c128.h">, <ref id="c128.h" name="c128.h">,
<ref id="cx16.h" name="cx16.h">/ <ref id="cx16.h" name="cx16.h">/
<tag/Declaration/ <tag/Declaration/
<tt>unsigned __fastcall__ videomode (unsigned Mode); /* for apple2enh and c128 */</tt><newline> <tt>unsigned __fastcall__ videomode (unsigned Mode); /* for c128 */</tt><newline>
<tt>signed char __fastcall__ videomode (signed char Mode); /* for cx16 */</tt> <tt>signed char __fastcall__ videomode (signed char Mode); /* for apple2 and cx16 */</tt>
<tag/Description/Switch to a 40- or 80-column text or graphics mode, depending <tag/Description/Switch to a 40- or 80-column text or graphics mode, depending
on the argument. If the requested mode is already active, nothing happens. The on the argument. If the requested mode is already active, nothing happens. The
old mode is returned from the call. old mode is returned from the call.
<tag/Notes/<itemize> <tag/Notes/<itemize>
<item>The function is specific to the Commodore 128, the enhanced Apple //e, <item>The function is specific to the Commodore 128, the Apple II,
and the Commander X16. and the Commander X16.
<item>This function replaces <ref id="toggle_videomode" <item>This function replaces <ref id="toggle_videomode"
name="toggle_videomode">. name="toggle_videomode">.
<item>The function is available as only a fastcall function, so it may be used <item>The function is available as only a fastcall function, so it may be used
only in the presence of a prototype. only in the presence of a prototype.
<item>On Apple II, this functions returns the previously active video mode, or -1
if the mode is not supported due to lack of hardware.
</itemize> </itemize>
<tag/Availability/C128, enhanced Apple //e, and CX16 <tag/Availability/C128, Apple II, and CX16
<tag/See also/ <tag/See also/
<ref id="fast" name="fast">, <ref id="fast" name="fast">,
<ref id="isfast" name="isfast">, <ref id="isfast" name="isfast">,

View File

@@ -83,7 +83,57 @@
#define CH_CURS_LEFT 0x08 #define CH_CURS_LEFT 0x08
#define CH_CURS_RIGHT 0x15 #define CH_CURS_RIGHT 0x15
#if !defined(__APPLE2ENH__) #if defined(__APPLE2ENH__)
/* MouseText-based functions for boxes and lines drawing */
void mt_chline (unsigned char length);
void mt_cvline (unsigned char length);
void mt_chlinexy (unsigned char x, unsigned char y, unsigned char length);
void mt_cvlinexy (unsigned char x, unsigned char y, unsigned char length);
#define CH_HLINE 0x5F
#define CH_VLINE 0xDF
#define CH_ULCORNER 0x5F
#define CH_URCORNER 0x20
#define CH_LLCORNER 0xD4
#define CH_LRCORNER 0xDF
#define CH_TTEE 0x5F
#define CH_BTEE 0xD4
#define CH_LTEE 0xD4
#define CH_RTEE 0xDF
#define CH_CROSS 0xD4
#define _chline(length) mt_chline(length)
#define _chlinexy(x,y,length) mt_chlinexy(x,y,length)
#define _cvline(length) mt_cvline(length)
#define _cvlinexy(x,y,length) mt_cvlinexy(x,y,length)
#else
/* Functions that don't depend on MouseText to draw boxes and lines */
void dyn_chline (unsigned char h, unsigned char length);
void dyn_cvline (unsigned char v, unsigned char length);
void dyn_chlinexy (unsigned char h, unsigned char x, unsigned char y, unsigned char length);
void dyn_cvlinexy (unsigned char v, unsigned char x, unsigned char y, unsigned char length);
#if defined(DYN_BOX_DRAW)
/* When the user defines DYN_BOX_DRAW, we'll adapt to the machine
** we run on.
*/
extern char CH_HLINE;
extern char CH_VLINE;
extern char CH_ULCORNER;
extern char CH_URCORNER;
extern char CH_LLCORNER;
extern char CH_LRCORNER;
extern char CH_TTEE;
extern char CH_BTEE;
extern char CH_LTEE;
extern char CH_RTEE;
extern char CH_CROSS;
#else
/* Otherwise, fallback to safety and don't use MouseText at all. */
#define CH_HLINE '-' #define CH_HLINE '-'
#define CH_VLINE '!' #define CH_VLINE '!'
#define CH_ULCORNER '+' #define CH_ULCORNER '+'
@@ -95,7 +145,14 @@
#define CH_LTEE '+' #define CH_LTEE '+'
#define CH_RTEE '+' #define CH_RTEE '+'
#define CH_CROSS '+' #define CH_CROSS '+'
#endif #endif /* DYN_BOX_DRAW */
#define _chline(length) dyn_chline(CH_HLINE, length)
#define _chlinexy(x, y, length) dyn_chlinexy(CH_HLINE, x ,y, length)
#define _cvline(length) dyn_cvline(CH_VLINE, length)
#define _cvlinexy(x, y, length) dyn_cvlinexy(CH_VLINE, x, y, length)
#endif /* __APPLE2ENH__ */
/* Masks for joy_read */ /* Masks for joy_read */
#define JOY_UP_MASK 0x10 #define JOY_UP_MASK 0x10
@@ -127,6 +184,12 @@
#define TV_PAL 1 #define TV_PAL 1
#define TV_OTHER 2 #define TV_OTHER 2
/* Video modes */
#define VIDEOMODE_40x24 0x15
#define VIDEOMODE_80x24 0x00
#define VIDEOMODE_40COL VIDEOMODE_40x24
#define VIDEOMODE_80COL VIDEOMODE_80x24
extern unsigned char _dos_type; extern unsigned char _dos_type;
/* Valid _dos_type values: /* Valid _dos_type values:
** **
@@ -255,6 +318,11 @@ unsigned char __fastcall__ allow_lowercase (unsigned char onoff);
*/ */
#endif #endif
signed char __fastcall__ videomode (unsigned mode);
/* Set the video mode, return the old mode, or -1 if 80-column hardware is not
** installed. Call with one of the VIDEOMODE_xx constants.
*/
/* End of apple2.h */ /* End of apple2.h */

View File

@@ -57,18 +57,6 @@
#define CH_CURS_UP 0x0B #define CH_CURS_UP 0x0B
#define CH_CURS_DOWN 0x0A #define CH_CURS_DOWN 0x0A
#define CH_HLINE 0x5F
#define CH_VLINE 0xDF
#define CH_ULCORNER 0x5F
#define CH_URCORNER 0x20
#define CH_LLCORNER 0xD4
#define CH_LRCORNER 0xDF
#define CH_TTEE 0x5F
#define CH_BTEE 0xD4
#define CH_LTEE 0xD4
#define CH_RTEE 0xDF
#define CH_CROSS 0xD4
/* These are defined to be OpenApple + NumberKey */ /* These are defined to be OpenApple + NumberKey */
#define CH_F1 0xB1 #define CH_F1 0xB1
#define CH_F2 0xB2 #define CH_F2 0xB2
@@ -81,12 +69,6 @@
#define CH_F9 0xB9 #define CH_F9 0xB9
#define CH_F10 0xB0 #define CH_F10 0xB0
/* Video modes */
#define VIDEOMODE_40x24 0x15
#define VIDEOMODE_80x24 0x00
#define VIDEOMODE_40COL VIDEOMODE_40x24
#define VIDEOMODE_80COL VIDEOMODE_80x24
/*****************************************************************************/ /*****************************************************************************/
@@ -112,11 +94,6 @@ extern void a2e_lo_tgi[];
unsigned __fastcall__ videomode (unsigned mode);
/* Set the video mode, return the old mode. Call with one of the VIDEOMODE_xx
** constants.
*/
void waitvsync (void); void waitvsync (void);
/* Wait for start of next frame */ /* Wait for start of next frame */

View File

@@ -216,7 +216,18 @@ void __fastcall__ cputhex16 (unsigned val);
# define cpeekrevers() _cpeekrevers() # define cpeekrevers() _cpeekrevers()
#endif #endif
#ifdef _chline
# define chline(len) _chline(len)
#endif
#ifdef _cvline
# define cvline(len) _cvline(len)
#endif
#ifdef _chlinexy
# define chlinexy(x, y, len) _chlinexy(x, y, len)
#endif
#ifdef _cvlinexy
# define cvlinexy(x, y, len) _cvlinexy(x, y, len)
#endif
/* End of conio.h */ /* End of conio.h */
#endif #endif

73
libsrc/apple2/boxchars.s Normal file
View File

@@ -0,0 +1,73 @@
;
; Colin Leroy-Mira and Oliver Schmidt, 26.05.2025
;
; Initialize box-drawing characters according to
; MouseText availability
;
.ifndef __APPLE2ENH__
.constructor initboxchars
.import machinetype
.export _CH_HLINE
.export _CH_VLINE
.export _CH_ULCORNER
.export _CH_URCORNER
.export _CH_LLCORNER
.export _CH_LRCORNER
.export _CH_TTEE
.export _CH_BTEE
.export _CH_LTEE
.export _CH_RTEE
.export _CH_CROSS
.segment "ONCE"
initboxchars:
bit machinetype ; IIe enhanced or newer?
bvs out
ldx #NUM_BOXCHARS ; No mousetext, patch characters
: lda std_boxchars,x
sta boxchars,x
dex
bpl :-
out: rts
; Replacement chars for when MouseText is not available
std_boxchars: .byte '!'
.byte '-'
.byte '+'
.byte '+'
.byte '+'
.byte '+'
.data
; MouseText-based box characters
boxchars:
VERT: .byte $DF
HORIZ: .byte $5F
ULCORNER: .byte $5F
URCORNER: .byte $20
LLCORNER: .byte $D4
LRCORNER: .byte $DF
NUM_BOXCHARS = *-boxchars
; exported symbols, referencing our 6 bytes
_CH_HLINE = HORIZ
_CH_VLINE = VERT
_CH_ULCORNER = ULCORNER
_CH_URCORNER = URCORNER
_CH_LLCORNER = LLCORNER
_CH_LRCORNER = LRCORNER
_CH_TTEE = ULCORNER
_CH_BTEE = LLCORNER
_CH_LTEE = LLCORNER
_CH_RTEE = LRCORNER
_CH_CROSS = LLCORNER
.endif ; not __APPLE2ENH__

View File

@@ -7,6 +7,10 @@
; ;
.export _cgetc .export _cgetc
.ifndef __APPLE2ENH__
.import machinetype
.endif
.import cursor, putchardirect .import cursor, putchardirect
.include "zeropage.inc" .include "zeropage.inc"
@@ -18,11 +22,14 @@ _cgetc:
beq :+ beq :+
; Show caret. ; Show caret.
.ifdef __APPLE2ENH__ .ifndef __APPLE2ENH__
lda #$7F | $80 ; Checkerboard, screen code
.else
lda #' ' | $40 ; Blank, flashing lda #' ' | $40 ; Blank, flashing
bit machinetype
bpl put_caret
.endif .endif
lda #$7F | $80 ; Checkerboard, screen code
put_caret:
jsr putchardirect ; Saves old character in tmp3 jsr putchardirect ; Saves old character in tmp3
; Wait for keyboard strobe. ; Wait for keyboard strobe.

View File

@@ -4,14 +4,24 @@
; char cpeekc (void); ; char cpeekc (void);
; ;
.ifndef __APPLE2ENH__
.import machinetype
.endif
.export _cpeekc .export _cpeekc
.include "apple2.inc" .include "apple2.inc"
_cpeekc: _cpeekc:
ldy CH ldy CH
.ifdef __APPLE2ENH__
sec ; Assume main memory sec ; Assume main memory
.ifndef __APPLE2ENH__
bit machinetype
bpl peek
.endif
bit RD80VID ; In 80 column mode? bit RD80VID ; In 80 column mode?
bpl peek ; No, just go ahead bpl peek ; No, just go ahead
lda OURCH lda OURCH
@@ -21,13 +31,12 @@ _cpeekc:
php php
sei ; No valid MSLOT et al. in aux memory sei ; No valid MSLOT et al. in aux memory
bit HISCR ; Assume SET80COL bit HISCR ; Assume SET80COL
.endif
peek: lda (BASL),Y ; Get character peek: lda (BASL),Y ; Get character
.ifdef __APPLE2ENH__
bcs :+ ; In main memory bcs :+ ; In main memory
bit LOWSCR bit LOWSCR
plp plp
: .endif
eor #$80 ; Invert high bit : eor #$80 ; Invert high bit
ldx #>$0000 ldx #>$0000
rts rts

View File

@@ -5,13 +5,13 @@
; void __fastcall__ cputc (char c); ; void __fastcall__ cputc (char c);
; ;
.ifdef __APPLE2ENH__
.constructor initconio .constructor initconio
.endif
.export _cputcxy, _cputc .export _cputcxy, _cputc
.export cputdirect, newline, putchar, putchardirect .export cputdirect, newline, putchar, putchardirect
.import gotoxy, VTABZ .import gotoxy, VTABZ
.ifndef __APPLE2ENH__ .ifndef __APPLE2ENH__
.import machinetype
.import uppercasemask .import uppercasemask
.endif .endif
@@ -22,12 +22,16 @@
.segment "ONCE" .segment "ONCE"
.ifdef __APPLE2ENH__
initconio: initconio:
.ifndef __APPLE2ENH__
bit machinetype
bmi :+
rts
:
.endif
sta SETALTCHAR ; Switch in alternate charset sta SETALTCHAR ; Switch in alternate charset
bit LORES ; Limit SET80COL-HISCR to text bit LORES ; Limit SET80COL-HISCR to text
rts rts
.endif
.code .code
@@ -52,14 +56,22 @@ _cputc:
cputdirect: cputdirect:
jsr putchar jsr putchar
.ifdef __APPLE2ENH__
.ifndef __APPLE2ENH__
bit machinetype
bpl :+
.endif
bit RD80VID ; In 80 column mode? bit RD80VID ; In 80 column mode?
bpl :+ bpl :+
inc OURCH ; Bump to next column inc OURCH ; Bump to next column
lda OURCH lda OURCH
.ifdef __APPLE2ENH__
bra check ; Must leave CH alone bra check ; Must leave CH alone
: .endif .else
inc CH ; Bump to next column jmp check
.endif
: inc CH ; Bump to next column
lda CH lda CH
check: cmp WNDWDTH check: cmp WNDWDTH
bcc done bcc done
@@ -67,13 +79,24 @@ check: cmp WNDWDTH
left: left:
.ifdef __APPLE2ENH__ .ifdef __APPLE2ENH__
stz CH ; Goto left edge of screen stz CH ; Goto left edge of screen
bit RD80VID ; In 80 column mode?
bpl done
stz OURCH ; Goto left edge of screen
.else .else
lda #$00 ; Goto left edge of screen lda #$00
sta CH sta CH
.endif .endif
.ifndef __APPLE2ENH__
bit machinetype
bpl done
.endif
bit RD80VID ; In 80 column mode?
bpl done
.ifdef __APPLE2ENH__
stz OURCH ; Goto left edge of screen
.else
sta OURCH
.endif
done: rts done: rts
newline: newline:
@@ -100,8 +123,14 @@ mask: and INVFLG ; Apply normal, inverse, flash
putchardirect: putchardirect:
tax tax
ldy CH ldy CH
.ifdef __APPLE2ENH__
sec ; Assume main memory sec ; Assume main memory
.ifndef __APPLE2ENH__
bit machinetype
bpl put
.endif
bit RD80VID ; In 80 column mode? bit RD80VID ; In 80 column mode?
bpl put ; No, just go ahead bpl put ; No, just go ahead
lda OURCH lda OURCH
@@ -111,14 +140,13 @@ putchardirect:
php php
sei ; No valid MSLOT et al. in aux memory sei ; No valid MSLOT et al. in aux memory
bit HISCR ; Assume SET80COL bit HISCR ; Assume SET80COL
.endif
put: lda (BASL),Y ; Get current character put: lda (BASL),Y ; Get current character
sta tmp3 ; Save old character for _cgetc sta tmp3 ; Save old character for _cgetc
txa txa
sta (BASL),Y sta (BASL),Y
.ifdef __APPLE2ENH__
bcs :+ ; In main memory bcs :+ ; In main memory
bit LOWSCR bit LOWSCR
plp plp
: .endif : rts
rts

41
libsrc/apple2/dynchline.s Normal file
View File

@@ -0,0 +1,41 @@
;
; Ullrich von Bassewitz, 08.08.1998
; Colin Leroy-Mira, 26.05.2025
;
; void __fastcall__ dyn_chlinexy (unsigned char c, unsigned char x, unsigned char y, unsigned char length);
; void __fastcall__ dyn_chline (unsigned char c, unsigned char length);
;
.ifndef __APPLE2ENH__
.export _dyn_chlinexy, _dyn_chline, chlinedirect
.import gotoxy, cputdirect, popa
.import machinetype
.include "zeropage.inc"
.include "apple2.inc"
_dyn_chlinexy:
pha ; Save the length
jsr gotoxy ; Call this one, will pop params
pla ; Restore the length and run into _chline
_dyn_chline:
pha
jsr popa ; Get the character to draw
eor #$80 ; Invert high bit
tax
pla
chlinedirect:
stx tmp1
cmp #$00 ; Is the length zero?
beq done ; Jump if done
sta tmp2
: lda tmp1 ; Screen code
jsr cputdirect ; Direct output
dec tmp2
bne :-
done: rts
.endif

40
libsrc/apple2/dyncvline.s Normal file
View File

@@ -0,0 +1,40 @@
;
; Ullrich von Bassewitz, 08.08.1998
; Colin Leroy-Mira, 26.05.2025
;
; void __fastcall__ dyn_cvlinexy (unsigned char c, unsigned char x, unsigned char y, unsigned char length);
; void __fastcall__ dyn_cvline (unsigned char c, unsigned char length);
;
.ifndef __APPLE2ENH__
.export _dyn_cvlinexy, _dyn_cvline
.import gotoxy, putchar, newline, popa
.import machinetype
.include "zeropage.inc"
_dyn_cvlinexy:
pha ; Save the length
jsr gotoxy ; Call this one, will pop params
pla ; Restore the length and run into _cvline
_dyn_cvline:
pha
jsr popa ; Get the character to draw
eor #$80 ; Invert high bit
tax
pla
stx tmp1
cmp #$00 ; Is the length zero?
beq done ; Jump if done
sta tmp2
: lda tmp1 ; Screen code
jsr putchar ; Write, no cursor advance
jsr newline ; Advance cursor to next line
dec tmp2
bne :-
done: rts
.endif

View File

@@ -4,6 +4,8 @@
; unsigned char get_ostype (void) ; unsigned char get_ostype (void)
; ;
; Priority higher than the default one so that things depending
; on ostype can get ostype set when called at normal priority
.constructor initostype, 9 .constructor initostype, 9
.export _get_ostype, ostype .export _get_ostype, ostype

View File

@@ -8,6 +8,10 @@
.export gotoxy, _gotoxy, _gotox .export gotoxy, _gotoxy, _gotox
.import popa, VTABZ .import popa, VTABZ
.ifndef __APPLE2ENH__
.import machinetype
.endif
.include "apple2.inc" .include "apple2.inc"
gotoxy: gotoxy:
@@ -22,9 +26,13 @@ _gotoxy:
_gotox: _gotox:
sta CH ; Store X sta CH ; Store X
.ifdef __APPLE2ENH__
.ifndef __APPLE2ENH__
bit machinetype
bpl :+
.endif
bit RD80VID ; In 80 column mode? bit RD80VID ; In 80 column mode?
bpl :+ bpl :+
sta OURCH ; Store X sta OURCH ; Store X
: .endif : rts
rts

View File

@@ -2,9 +2,8 @@
; Oliver Schmidt, 2013-05-31 ; Oliver Schmidt, 2013-05-31
; ;
.export em_libref, ser_libref, tgi_libref .export em_libref, ser_libref
.import _exit .import _exit
em_libref := _exit em_libref := _exit
ser_libref := _exit ser_libref := _exit
tgi_libref := _exit

View File

@@ -0,0 +1,24 @@
.ifndef __APPLE2ENH__
.constructor initmachinetype, 8
.import ostype
.export machinetype
.segment "ONCE"
initmachinetype:
ldx ostype
cpx #$31 ; Apple //e enhanced?
ror machinetype ; Carry to high bit
cpx #$30 ; Apple //e?
ror machinetype
rts
.data
; bit 7: Machine is a //e or newer
; bit 6: Machine is a //e enhanced or newer
machinetype: .byte 0
.endif

View File

@@ -9,6 +9,10 @@
.export _mouse_def_callbacks .export _mouse_def_callbacks
.ifndef __APPLE2ENH__
.import machinetype
.endif
.include "apple2.inc" .include "apple2.inc"
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
@@ -42,11 +46,14 @@ cursor = '+' | $40 ; Flashing crosshair
.endif .endif
getcursor: getcursor:
.ifdef __APPLE2ENH__ .ifndef __APPLE2ENH__
bit machinetype
bpl column
.endif
bit RD80VID ; In 80 column mode? bit RD80VID ; In 80 column mode?
bpl column ; No, skip bank switching bpl column ; No, skip bank switching
switch: bit LOWSCR ; Patched at runtime switch: bit LOWSCR ; Patched at runtime
.endif
column: ldx #$00 ; Patched at runtime column: ldx #$00 ; Patched at runtime
getscr: lda $0400,x ; Patched at runtime getscr: lda $0400,x ; Patched at runtime
cmp #cursor cmp #cursor
@@ -55,9 +62,7 @@ getscr: lda $0400,x ; Patched at runtime
setcursor: setcursor:
lda #cursor lda #cursor
setscr: sta $0400,x ; Patched at runtime setscr: sta $0400,x ; Patched at runtime
.ifdef __APPLE2ENH__
bit LOWSCR ; Doesn't hurt in 40 column mode bit LOWSCR ; Doesn't hurt in 40 column mode
.endif
rts rts
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
@@ -65,9 +70,7 @@ setscr: sta $0400,x ; Patched at runtime
.code .code
done: done:
.ifdef __APPLE2ENH__
bit LOWSCR ; Doesn't hurt in 40 column mode bit LOWSCR ; Doesn't hurt in 40 column mode
.endif
return: rts return: rts
; Hide the mouse cursor. ; Hide the mouse cursor.
@@ -108,14 +111,14 @@ movex:
inx inx
bcs :- bcs :-
stx column+1 stx column+1
.ifdef __APPLE2ENH__
; Patch switch anyway, it will just be skipped over if in 40-col mode
adc #7 / 2 ; Left or right half of 40-col column? adc #7 / 2 ; Left or right half of 40-col column?
ldx #<LOWSCR ; Columns 1,3,5..79 ldx #<LOWSCR ; Columns 1,3,5..79
bcs :+ bcs :+
.assert LOWSCR + 1 = HISCR, error .assert LOWSCR + 1 = HISCR, error
inx ; Columns 0,2,4..78 inx ; Columns 0,2,4..78
: stx switch+1 : stx switch+1
.endif
rts rts
; Move the mouse cursor y position to the value in A/X. ; Move the mouse cursor y position to the value in A/X.

View File

@@ -1,27 +1,26 @@
; ;
; Ullrich von Bassewitz, 08.08.1998 ; Ullrich von Bassewitz, 08.08.1998
; Colin Leroy-Mira, 26.05.2025
; ;
; void __fastcall__ chlinexy (unsigned char x, unsigned char y, unsigned char length); ; void __fastcall__ mt_chlinexy (unsigned char x, unsigned char y, unsigned char length);
; void __fastcall__ chline (unsigned char length); ; void __fastcall__ mt_chline (unsigned char length);
; ;
.export _chlinexy, _chline, chlinedirect .ifdef __APPLE2ENH__
.export _mt_chlinexy, _mt_chline, chlinedirect
.import gotoxy, cputdirect .import gotoxy, cputdirect
.include "zeropage.inc" .include "zeropage.inc"
.include "apple2.inc" .include "apple2.inc"
_chlinexy: _mt_chlinexy:
pha ; Save the length pha ; Save the length
jsr gotoxy ; Call this one, will pop params jsr gotoxy ; Call this one, will pop params
pla ; Restore the length and run into _chline pla ; Restore the length and run into _chline
_chline: _mt_chline:
.ifdef __APPLE2ENH__
ldx #'_' | $80 ; Underscore, screen code ldx #'_' | $80 ; Underscore, screen code
.else
ldx #'-' | $80 ; Minus, screen code
.endif
chlinedirect: chlinedirect:
stx tmp1 stx tmp1
@@ -33,3 +32,5 @@ chlinedirect:
dec tmp2 dec tmp2
bne :- bne :-
done: rts done: rts
.endif

View File

@@ -1,34 +1,32 @@
; ;
; Ullrich von Bassewitz, 08.08.1998 ; Ullrich von Bassewitz, 08.08.1998
; Colin Leroy-Mira, 26.05.2025
; ;
; void __fastcall__ cvlinexy (unsigned char x, unsigned char y, unsigned char length); ; void __fastcall__ mt_cvlinexy (unsigned char x, unsigned char y, unsigned char length);
; void __fastcall__ cvline (unsigned char length); ; void __fastcall__ mt_cvline (unsigned char length);
; ;
.export _cvlinexy, _cvline .ifdef __APPLE2ENH__
.export _mt_cvlinexy, _mt_cvline
.import gotoxy, putchar, newline .import gotoxy, putchar, newline
.include "zeropage.inc" .include "zeropage.inc"
_cvlinexy: _mt_cvlinexy:
pha ; Save the length pha ; Save the length
jsr gotoxy ; Call this one, will pop params jsr gotoxy ; Call this one, will pop params
pla ; Restore the length and run into _cvline pla ; Restore the length and run into _cvline
_cvline: _mt_cvline:
.ifdef __APPLE2ENH__
ldx #$5F ; Left vertical line MouseText character
.else
ldx #'!' | $80 ; Exclamation mark, screen code
.endif
stx tmp1
cmp #$00 ; Is the length zero? cmp #$00 ; Is the length zero?
beq done ; Jump if done beq done ; Jump if done
sta tmp2 sta tmp2
: lda tmp1 ; Screen code : lda #$5F ; Left vertical line MouseText character
jsr putchar ; Write, no cursor advance jsr putchar ; Write, no cursor advance
jsr newline ; Advance cursor to next line jsr newline ; Advance cursor to next line
dec tmp2 dec tmp2
bne :- bne :-
done: rts done: rts
.endif

View File

@@ -83,7 +83,10 @@ Y2 := ptr4
.byte $74, $67, $69 ; "tgi" .byte $74, $67, $69 ; "tgi"
.byte TGI_API_VERSION ; TGI API version number .byte TGI_API_VERSION ; TGI API version number
libref:
.addr $0000 ; Library reference .addr $0000 ; Library reference
.word 280 ; X resolution .word 280 ; X resolution
.word 192 ; Y resolution .word 192 ; Y resolution
.byte 8 ; Number of drawing colors .byte 8 ; Number of drawing colors
@@ -120,6 +123,10 @@ pages: .byte 2 ; Number of screens available
.bss .bss
.ifndef __APPLE2ENH__
machinetype: .res 1
.endif
; Absolute variables used in the code ; Absolute variables used in the code
ERROR: .res 1 ; Error code ERROR: .res 1 ; Error code
@@ -146,13 +153,22 @@ FONT:
; most of the time. ; most of the time.
; Must set an error code: NO ; Must set an error code: NO
INSTALL: INSTALL:
.ifdef __APPLE2ENH__ .ifndef __APPLE2ENH__
lda libref
ldx libref+1
sta ptr1
stx ptr1+1
ldy #$0
lda (ptr1),y
sta machinetype
bpl :+
.endif
; No page switching if 80 column store is enabled ; No page switching if 80 column store is enabled
bit RD80COL bit RD80COL
bpl :+ bpl :+
lda #$01 lda #$01
sta pages sta pages
: .endif :
; Fall through ; Fall through
@@ -175,10 +191,16 @@ INIT:
; Switch into graphics mode ; Switch into graphics mode
bit MIXCLR bit MIXCLR
bit HIRES bit HIRES
.ifdef __APPLE2ENH__
.ifndef __APPLE2ENH__
bit machinetype
bpl clr_txt
.endif
sta IOUDISON sta IOUDISON
bit DHIRESOFF bit DHIRESOFF
.endif
clr_txt:
bit TXTCLR bit TXTCLR
; Beagle Bros Shape Mechanic fonts don't ; Beagle Bros Shape Mechanic fonts don't
@@ -200,11 +222,14 @@ DONE:
bit TXTSET bit TXTSET
bit LOWSCR bit LOWSCR
.ifdef __APPLE2ENH__ .ifndef __APPLE2ENH__
bit machinetype
bpl reset_wndtop
.endif
; Limit SET80COL-HISCR to text ; Limit SET80COL-HISCR to text
bit LORES bit LORES
.endif
reset_wndtop:
; Reset the text window top ; Reset the text window top
lda #$00 lda #$00
sta WNDTOP sta WNDTOP

18
libsrc/apple2/tgiref.s Normal file
View File

@@ -0,0 +1,18 @@
;
; Colin Leroy-Mira, 2025-05-10
;
.export tgi_libref
.import _exit
.ifndef __APPLE2ENH__
.import machinetype
tgi_libref := machinetype
.else
tgi_libref := _exit
.endif

View File

@@ -1,17 +1,40 @@
; ;
; Oliver Schmidt, 07.09.2009 ; Oliver Schmidt, 07.09.2009
; ;
; unsigned __fastcall__ videomode (unsigned mode); ; signed char __fastcall__ videomode (unsigned mode);
; ;
.ifdef __APPLE2ENH__
.export _videomode .export _videomode
.ifndef __APPLE2ENH__
.import machinetype
.endif
.import returnFFFF
.include "apple2.inc" .include "apple2.inc"
.include "mli.inc"
VIDEOMODE_40x24 = $15
VIDEOMODE_80x24 = $00
.segment "LOWCODE" .segment "LOWCODE"
_videomode: _videomode:
; Functionally equivalent to previous assumption that
; __APPLE2ENH__ == 80 columns hardware present. Will be
; correctly checked in the very near future.
.ifndef __APPLE2ENH__
bit machinetype
bvs set_mode
; No 80 column card, return error if requested mode is 80cols
cmp #VIDEOMODE_40x24
beq out
jmp returnFFFF
set_mode:
.endif
; Get and save current videomode flag ; Get and save current videomode flag
bit RD80VID bit RD80VID
php php
@@ -31,10 +54,8 @@ _videomode:
; Return ctrl-char code for setting previous ; Return ctrl-char code for setting previous
; videomode using the saved videomode flag ; videomode using the saved videomode flag
lda #$15 ; Ctrl-char code for 40 cols lda #VIDEOMODE_40x24
plp plp
bpl :+ bpl out
lda #$00 ; Ctrl-char code for 80 cols lda #VIDEOMODE_80x24
: rts ; X was preserved all the way out: rts ; X was preserved all the way
.endif ; __APPLE2ENH__

View File

@@ -4,16 +4,23 @@
; unsigned char wherex (void); ; unsigned char wherex (void);
; ;
.ifndef __APPLE2ENH__
.import machinetype
.endif
.export _wherex .export _wherex
.include "apple2.inc" .include "apple2.inc"
_wherex: _wherex:
lda CH lda CH
.ifdef __APPLE2ENH__ .ifndef __APPLE2ENH__
bit machinetype
bpl :+
.endif
bit RD80VID ; In 80 column mode? bit RD80VID ; In 80 column mode?
bpl :+ bpl :+
lda OURCH lda OURCH
: .endif
ldx #>$0000 : ldx #>$0000
rts rts

View File

@@ -9,6 +9,15 @@
* *
*/ */
/* Box drawing characters are usually constant expressions. However, there
* are scenarios where this is not the case. To ensure compatibility with
* code that assumes they are constant expressions, the scenarios in question
* must be explicitly enabled by defining DYN_BOX_DRAW. Currently, the only
* such scenario is the apple2 target. There, DYN_BOX_DRAW can be used to
* enable the use of MouseText characters on exactly those machines that
* support them.
*/
#define DYN_BOX_DRAW
#include <conio.h> #include <conio.h>
#include <string.h> #include <string.h>
@@ -34,6 +43,10 @@
#define CH_VLINE '!' #define CH_VLINE '!'
#endif #endif
#if defined(DYN_BOX_DRAW)
static char grid[5][5];
#else
static char grid[5][5] = { static char grid[5][5] = {
{CH_ULCORNER, CH_HLINE, CH_TTEE, CH_HLINE, CH_URCORNER}, {CH_ULCORNER, CH_HLINE, CH_TTEE, CH_HLINE, CH_URCORNER},
{CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE }, {CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE },
@@ -41,6 +54,35 @@ static char grid[5][5] = {
{CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE }, {CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE },
{CH_LLCORNER, CH_HLINE, CH_BTEE, CH_HLINE, CH_LRCORNER} {CH_LLCORNER, CH_HLINE, CH_BTEE, CH_HLINE, CH_LRCORNER}
}; };
#endif
#if defined(DYN_BOX_DRAW)
static void init_grid(void)
{
/* Programmatically fill the array with extern chars
* instead of constants. */
grid[0][0] = CH_ULCORNER;
grid[2][0] = CH_LTEE;
grid[4][0] = CH_LLCORNER;
grid[0][2] = CH_TTEE;
grid[2][2] = CH_CROSS;
grid[4][2] = CH_BTEE;
grid[0][4] = CH_URCORNER;
grid[2][4] = CH_RTEE;
grid[4][4] = CH_LRCORNER;
grid[1][1] = grid[1][3] =
grid[3][1] = grid[3][3] = ' ';
grid[1][0] = grid[1][2] = grid[1][4] =
grid[3][0] = grid[3][2] = grid[3][4] = CH_VLINE;
grid[0][1] = grid[0][3] =
grid[2][1] = grid[2][3] =
grid[4][1] = grid[4][3] = CH_HLINE;
}
#endif
#define LINE_COLORTEST 3 #define LINE_COLORTEST 3
#define LINE_PEEKTEST 11 #define LINE_PEEKTEST 11
@@ -152,6 +194,11 @@ void main(void)
joy_install(joy_static_stddrv); joy_install(joy_static_stddrv);
#endif #endif
#if defined(DYN_BOX_DRAW)
init_grid();
#endif
clrscr(); clrscr();
screensize(&xsize, &ysize); screensize(&xsize, &ysize);
cputs("cc65 conio test\n\r"); cputs("cc65 conio test\n\r");