Macro-based implementation of screen layout configuration modules.

This commit is contained in:
Stephan Mühlstrasser 2015-03-22 22:45:53 +01:00
parent b4bab018ac
commit 7fb206e381
8 changed files with 250 additions and 159 deletions

View File

@ -6,7 +6,7 @@
<author>
<url url="mailto:stephan.muehlstrasser@web.de" name="Stephan M&uuml;hlstrasser">,<newline>
<url url="mailto:greg.king5@verizon.net" name="Greg King">
<date>2015-03-08
<date>2015-03-17
<abstract>
An overview over the Ohio Scientific runtime system as it is implemented for the cc65 C
@ -33,7 +33,7 @@ information.
<sect>Targets<p>
Currently the target "osic1p" is implemented. This works for the Ohio Scientific
Challenger 1P machine.
Challenger 1P machine and for the Briel Superboard /// replica.
<sect>Program file formats<p>
@ -123,7 +123,7 @@ Challenger 1P, which is implicitly used via <tt/-t osic1p/. The
osic1p package comes with additional secondary linker config files, which are
used via <tt/-t osic1p -C &lt;configfile&gt;/.
<sect1>default config file (<tt/osic1p.cfg/)<p>
<sect1>Default config file (<tt/osic1p.cfg/)<p>
The default configuration is tailored to C programs.
@ -161,6 +161,36 @@ There is no specific support for direct hardware access.
There are no loadable drivers available.
<sect>Support for different screen layouts<p>
By default the conio library uses a 24 columns by 24 lines screen layout
for the Challenger 1P, like under BASIC. In addition to that there is support
for other screen layouts with extra modules.
There is a module <tt/screen-c1p-24x24.o/ in the OSI-specific
cc65 runtime library that contains all conio functions that depend
on the screen layout. No further configuration is needed for using the
default screen layout of the Challenger 1P.
For other screen layouts additional versions of the screen module are
available. The linker finds these modules without further configuration
if they are specified on the compiler or linker command line. The
extra module then overrides the default module.
Sample <tt/cl65/ command line to override the default screen
module with the module <tt/osic1p-screen-s3-32x28.o/:
<tscreen><verb>
cl65 -o hello -t osic1p osic1p-screen-s3-32x28.o hello.c
</verb></tscreen>
Currently the following extra screen configuration modules are implemented:
<itemize>
<item><tt>osic1p-screen-s3-32x28.o</tt>: 32 columns by 28 lines mode
for Briel Superboard ///</item>
</itemize>
<sect>Limitations<p>
<sect1>stdio implementation<p>
@ -200,3 +230,4 @@ freely, subject to the following restrictions:
</enum>
</article>

View File

@ -1,19 +0,0 @@
;
; based on PET implementation
;
; originally by:
; Ullrich von Bassewitz, 26.10.2000
;
; Screen size variables
;
.export screensize
.include "extzp.inc"
.include "osic1p.inc"
.proc screensize
ldx #SCR_WIDTH
ldy #SCR_HEIGHT
rts
.endproc

View File

@ -1,31 +0,0 @@
;
; void clrscr (void);
;
.export _clrscr
.import plot
.include "extzp.inc"
.include "osic1p.inc"
; Adapted from the Challenger Character Graphics
; Reference Manual, "2.3.3 MACHINE LANGUAGE SCREEN CLEAR"
; This is self-modifying code!
BANKS = VIDEORAMSIZE / $100
_clrscr:
lda #' '
ldy #BANKS
ldx #$00
staloc:
sta SCRNBASE,X
inx
bne staloc
inc staloc+2
dey
bne staloc
lda #>(SCRNBASE) ; Load high byte
sta staloc+2 ; Restore base address
lda #$00 ; Cursor in upper left corner
sta CURS_X
sta CURS_Y
jmp plot ; Set the cursor position

View File

@ -1,100 +0,0 @@
;
; cputc/cputcxy for Challenger 1P
; Based on PET/CBM implementation
;
; void cputcxy (unsigned char x, unsigned char y, char c);
; void cputc (char c);
;
.export _cputcxy, _cputc, cputdirect, putchar
.export newline, plot
.import popa, _gotoxy
.include "osic1p.inc"
.include "extzp.inc"
FIRSTVISC = $85 ; Offset of first visible character in video RAM
LINEDIST = $20 ; Offset in video RAM between two lines
BLOCKSIZE = $100 ; Size of block to scroll
_cputcxy:
pha ; Save C
jsr popa ; Get Y
jsr _gotoxy ; Set cursor, drop x
pla ; Restore C
; Plot a character - also used as internal function
_cputc: cmp #$0A ; CR?
bne L1
lda #0
sta CURS_X
beq plot ; Recalculate pointers
L1: cmp #$0D ; LF?
beq newline ; Recalculate pointers
cputdirect:
jsr putchar ; Write the character to the screen
; Advance cursor position
advance:
cpy #(SCR_WIDTH - 1)
bne L3
jsr newline ; New line
ldy #$FF ; + cr
L3: iny
sty CURS_X
rts
newline:
inc CURS_Y
lda CURS_Y
cmp #SCR_HEIGHT ; Screen height
bne plot
dec CURS_Y ; Bottom of screen reached, scroll
ldx #0
scroll:
.repeat 3, I ; Scroll screen in three blocks of size
; BLOCKSIZE
lda SCRNBASE+(I*BLOCKSIZE)+FIRSTVISC+LINEDIST,x
sta SCRNBASE+(I*BLOCKSIZE)+FIRSTVISC,x
.endrepeat
inx
bne scroll
lda #' ' ; Clear bottom line of screen
bottom:
sta SCRNBASE+(3*BLOCKSIZE)+FIRSTVISC,x
inx
cpx #SCR_WIDTH
bne bottom
plot: ldy CURS_Y
lda ScrLo,y
sta SCREEN_PTR
lda ScrHi,y
sta SCREEN_PTR+1
rts
; Write one character to the screen without doing anything else, return X
; position in Y
putchar:
ldy CURS_X
sta (SCREEN_PTR),y ; Set char
rts
; Screen address tables - offset to real screen
.rodata
ScrLo: .byte $85, $A5, $C5, $E5, $05, $25, $45, $65
.byte $85, $A5, $C5, $E5, $05, $25, $45, $65
.byte $85, $A5, $C5, $E5, $05, $25, $45, $65
.byte $85
ScrHi: .byte $D0, $D0, $D0, $D0, $D1, $D1, $D1, $D1
.byte $D1, $D1, $D1, $D1, $D2, $D2, $D2, $D2
.byte $D2, $D2, $D2, $D2, $D3, $D3, $D3, $D3
.byte $D3

View File

@ -0,0 +1,16 @@
;
; Implementation of screen-layout related functions for Superboard ///
;
.include "../osiscreen.inc"
S3_SCR_BASE := $D000 ; Base of Superboard /// video RAM
S3_VRAM_SIZE = $0400 ; Size of Superboard /// video RAM (1 kB)
S3_SCR_WIDTH = $20 ; Screen width
S3_SCR_HEIGHT = $1C ; Screen height
S3_SCR_FIRSTCHAR = $80 ; Offset of cursor position (0, 0) from base
; of video RAM
S3_SCROLL_DIST = $20 ; Memory distance for scrolling by one line
osi_screen_funcs S3_SCR_BASE, S3_VRAM_SIZE, S3_SCR_FIRSTCHAR, \
S3_SCR_WIDTH, S3_SCR_HEIGHT, S3_SCROLL_DIST

View File

@ -1,10 +1,4 @@
; Addresses
SCRNBASE := $D000 ; Base of video RAM
INPUTC := $FD00 ; Input character from keyboard
RESET := $FF00 ; Reset address, show boot prompt
KBD := $DF00 ; Polled keyboard register
; Other definitions
VIDEORAMSIZE = $0400 ; Size of C1P video RAM (1 kB)
SCR_WIDTH = $18 ; Screen width
SCR_HEIGHT = $18 ; Screen height

184
libsrc/osic1p/osiscreen.inc Normal file
View File

@ -0,0 +1,184 @@
;
; Macro definitions for screen layout modules
;
.include "extzp.inc"
.linecont +
;
; Internal function for screensize()
;
.macro osi_screensize ScrWidth, ScrHeight
; Macro implementation of internal screensize
; function for given width and height in
; characters
.export screensize
.proc screensize
ldx #ScrWidth
ldy #ScrHeight
rts
.endproc
.endmacro
;
; void clrscr (void);
;
.macro osi_clrscr ScrBase, ScrRamSize
.export _clrscr
.proc _clrscr
lda #<ScrBase ; Fill whole video RAM with blanks by calling
ldx #>ScrBase ; memset appropriately
jsr pushax
lda #' '
ldx #$00
jsr pushax
lda #<ScrRamSize
ldx #>ScrRamSize
jsr _memset
lda #$00 ; Cursor in upper left corner
sta CURS_X
sta CURS_Y
jmp plot ; Set the cursor position
.endproc
.endmacro
;
; cputc/cputcxy for Challenger 1P
; Based on PET/CBM implementation
;
.macro osi_cputfuncs ScrBase, ScrFirstChar, ScrWidth, ScrHeight, \
ScrollDist, ScrLo, ScrHi
; Number of characters to move for scrolling
; by one line
ScrollLength = (ScrHeight - 1) * ScrollDist
;
; void cputcxy (unsigned char x, unsigned char y, char c);
; void cputc (char c);
;
.export _cputcxy, _cputc, cputdirect, putchar
.export newline, plot
_cputcxy:
pha ; Save C
jsr popa ; Get Y
jsr _gotoxy ; Set cursor, drop x
pla ; Restore C
; Plot a character - also used as internal function
_cputc: cmp #$0A ; CR?
bne L1
lda #0
sta CURS_X
beq plot ; Recalculate pointers
L1: cmp #$0D ; LF?
beq newline ; Recalculate pointers
cputdirect:
jsr putchar ; Write the character to the screen
; Advance cursor position, register Y contains horizontal position after
; putchar
cpy #(ScrWidth - 1) ; Check whether line is full
bne L3
jsr newline ; New line
ldy #$FF ; + cr
L3: iny
sty CURS_X
rts
newline:
inc CURS_Y
lda CURS_Y
cmp #ScrHeight ; Screen height
bne plot
dec CURS_Y ; Bottom of screen reached, scroll
; Scroll destination address
lda #<(ScrBase + ScrFirstChar)
ldx #>(ScrBase + ScrFirstChar)
jsr pushax
; Scroll source address
lda #<(ScrBase + ScrFirstChar + ScrollDist)
ldx #>(ScrBase + ScrFirstChar + ScrollDist)
jsr pushax
; Number of characters to move
lda #<ScrollLength
ldx #>ScrollLength
jsr _memmove
; Address of first character in last line
; of screen
lda #<(ScrBase + ScrFirstChar + ScrollLength)
sta ptr1
lda #>(ScrBase + ScrFirstChar + ScrollLength)
sta ptr1+1
ldy #ScrWidth ; Fill last line with blanks
lda #' '
clrln: sta (ptr1),y
dey
bpl clrln
plot: ldy CURS_Y
lda ScrLo,y
sta SCREEN_PTR
lda ScrHi,y
sta SCREEN_PTR+1
rts
; Write one character to the screen without doing anything else, return X
; position in register Y
putchar:
ldy CURS_X
sta (SCREEN_PTR),y ; Set char
rts
.endmacro
.macro osi_screen_funcs ScrBase, ScrRamSize, ScrFirstChar, \
ScrWidth, ScrHeight, ScrollDist
.import popa, _gotoxy
.import _memmove, _memset, pushax
.importzp ptr1
.rodata
; Screen address tables - offset to real screen
ScrTabLo:
.repeat ScrHeight, I
.byte <(ScrBase + ScrFirstChar + I * ScrollDist)
.endrep
ScrTabHi:
.repeat ScrHeight, I
.byte >(ScrBase + ScrFirstChar + I * ScrollDist)
.endrep
.code
osi_cputfuncs ScrBase, ScrFirstChar, ScrWidth, ScrHeight, \
ScrollDist, ScrTabLo, ScrTabHi
osi_screensize ScrWidth, ScrHeight
osi_clrscr ScrBase, ScrRamSize
.endmacro

View File

@ -0,0 +1,16 @@
;
; Implementation of screen-layout related functions for Challenger 1P
;
.include "osiscreen.inc"
C1P_SCR_BASE := $D000 ; Base of C1P video RAM
C1P_VRAM_SIZE = $0400 ; Size of C1P video RAM (1 kB)
C1P_SCR_WIDTH = $18 ; Screen width
C1P_SCR_HEIGHT = $18 ; Screen height
C1P_SCR_FIRSTCHAR = $85 ; Offset of cursor position (0, 0) from base
; of video RAM
C1P_SCROLL_DIST = $20 ; Memory distance for scrolling by one line
osi_screen_funcs C1P_SCR_BASE, C1P_VRAM_SIZE, C1P_SCR_FIRSTCHAR, \
C1P_SCR_WIDTH, C1P_SCR_HEIGHT, C1P_SCROLL_DIST