Pull to fix extra changes in PR #863
This commit is contained in:
Bas Wassink
2019-03-24 20:49:53 +01:00
313 changed files with 10597 additions and 7389 deletions

View File

@@ -93,7 +93,7 @@ INSTALL = install
define INSTALL_recipe
$(if $(PREFIX),,$(error variable `PREFIX' must be set))
$(if $(PREFIX),,$(error variable "PREFIX" must be set))
$(INSTALL) -d $(DESTDIR)$(datadir)/$(dir)
$(INSTALL) -m0644 ../$(dir)/*.* $(DESTDIR)$(datadir)/$(dir)

View File

@@ -44,15 +44,15 @@
.addr $0000
; Jump table
.addr INSTALL
.addr UNINSTALL
.addr OPEN
.addr CLOSE
.addr GET
.addr PUT
.addr STATUS
.addr IOCTL
.addr IRQ
.addr SER_INSTALL
.addr SER_UNINSTALL
.addr SER_OPEN
.addr SER_CLOSE
.addr SER_GET
.addr SER_PUT
.addr SER_STATUS
.addr SER_IOCTL
.addr SER_IRQ
;----------------------------------------------------------------------------
; I/O definitions
@@ -141,23 +141,23 @@ IdTableLen = * - IdValTable
.code
;----------------------------------------------------------------------------
; INSTALL: Is called after the driver is loaded into memory. If possible,
; SER_INSTALL: Is called after the driver is loaded into memory. If possible,
; check if the hardware is present. Must return an SER_ERR_xx code in a/x.
;
; Since we don't have to manage the IRQ vector on the Apple II, this is
; actually the same as:
;
; UNINSTALL: Is called before the driver is removed from memory.
; SER_UNINSTALL: Is called before the driver is removed from memory.
; No return code required (the driver is removed from memory on return).
;
; and:
;
; CLOSE: Close the port and disable interrupts. Called without parameters.
; SER_CLOSE: Close the port and disable interrupts. Called without parameters.
; Must return an SER_ERR_xx code in a/x.
INSTALL:
UNINSTALL:
CLOSE:
SER_INSTALL:
SER_UNINSTALL:
SER_CLOSE:
ldx Index ; Check for open port
beq :+
@@ -172,16 +172,16 @@ CLOSE:
rts
;----------------------------------------------------------------------------
; OPEN: A pointer to a ser_params structure is passed in ptr1.
; SER_OPEN: A pointer to a ser_params structure is passed in ptr1.
; Must return an SER_ERR_xx code in a/x.
OPEN:
SER_OPEN:
ldx #<$C000
stx ptr2
lda #>$C000
ora Slot
sta ptr2+1
; Check Pascal 1.1 Firmware Protocol ID bytes
: ldy IdOfsTable,x
lda IdValTable,x
@@ -190,7 +190,7 @@ OPEN:
inx
cpx #IdTableLen
bcc :-
; Convert slot to I/O register index
lda Slot
asl
@@ -273,11 +273,11 @@ InvBaud:lda #<SER_ERR_BAUD_UNAVAIL
rts
;----------------------------------------------------------------------------
; GET: Will fetch a character from the receive buffer and store it into the
; SER_GET: Will fetch a character from the receive buffer and store it into the
; variable pointed to by ptr1. If no data is available, SER_ERR_NO_DATA is
; returned.
GET:
SER_GET:
ldx Index
ldy SendFreeCnt ; Send data if necessary
iny ; Y == $FF?
@@ -315,10 +315,10 @@ GET:
rts
;----------------------------------------------------------------------------
; PUT: Output character in A.
; SER_PUT: Output character in A.
; Must return an SER_ERR_xx code in a/x.
PUT:
SER_PUT:
ldx Index
; Try to send
@@ -348,10 +348,10 @@ PUT:
rts
;----------------------------------------------------------------------------
; STATUS: Return the status in the variable pointed to by ptr1.
; SER_STATUS: Return the status in the variable pointed to by ptr1.
; Must return an SER_ERR_xx code in a/x.
STATUS:
SER_STATUS:
ldx Index
lda ACIA_STATUS,x
ldx #$00
@@ -360,11 +360,11 @@ STATUS:
rts
;----------------------------------------------------------------------------
; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; specific data in ptr1, and the ioctl code in A.
; Must return an SER_ERR_xx code in a/x.
IOCTL:
SER_IOCTL:
; Check data msb and code to be 0
ora ptr1+1
bne :+
@@ -384,12 +384,12 @@ IOCTL:
rts
;----------------------------------------------------------------------------
; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
; SER_IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
; registers are already saved, no parameters are passed, but the carry flag
; is clear on entry. The routine must return with carry set if the interrupt
; was handled, otherwise with carry clear.
IRQ:
SER_IRQ:
ldx Index ; Check for open port
beq Done
lda ACIA_STATUS,x ; Check ACIA status for receive interrupt
@@ -431,7 +431,7 @@ Again: lda SendFreeCnt
lda ACIA_STATUS,x
and #$10
bne Send
bit tmp1 ; Keep trying if must try hard
bit tmp1 ; Keep trying if must try hard
bmi Again
Quit: rts

View File

@@ -1,5 +1,5 @@
;
; Mark Keates, Christian Groessler
; Mark Keates, Christian Groessler, Piotr Fusik
;
; void cputcxy (unsigned char x, unsigned char y, char c);
; void cputc (char c);
@@ -30,16 +30,13 @@ L4: cmp #$0A ; LF
cmp #ATEOL ; Atari-EOL?
beq newline
tay
rol a
rol a
rol a
rol a
and #3
tax
tya
and #$9f
ora ataint,x
asl a ; shift out the inverse bit
adc #$c0 ; grab the inverse bit; convert ATASCII to screen code
bpl codeok ; screen code ok?
eor #$40 ; needs correction
codeok: lsr a ; undo the shift
bcc cputdirect
eor #$80 ; restore the inverse bit
cputdirect: ; accepts screen code
jsr putchar
@@ -89,6 +86,3 @@ putchar:
ldy COLCRS
sta (ptr4),y
jmp setcursor
.rodata
ataint: .byte 64,0,32,96

View File

@@ -134,6 +134,7 @@ YPosWrk: .res 2
irq_enabled: .res 1 ; flag indicating that the high frequency polling interrupt is enabled
old_porta_vbi: .res 1 ; previous PORTA value of the VBI interrupt (IRQ)
how_long: .res 1 ; counter for how many VBI interrupts the mouse hasn't been moved
in_irq: .res 1 ; flag indicating high-frequency polling interrupt is active
.if .defined (AMIGA_MOUSE) .or .defined (ST_MOUSE)
dumx: .res 1
@@ -145,11 +146,11 @@ oldval: .res 1
.endif
.ifndef __ATARIXL__
OldT1: .res 2
OldT2: .res 2
.else
.data
set_VTIMR1_handler:
set_VTIMR2_handler:
.byte $4C, 0, 0
.endif
@@ -226,29 +227,29 @@ INSTALL:
; Setup pointer to wrapper install/deinstall function.
lda libref
sta set_VTIMR1_handler+1
sta set_VTIMR2_handler+1
lda libref+1
sta set_VTIMR1_handler+2
sta set_VTIMR2_handler+2
; Install my handler.
sec
lda #<T1Han
ldx #>T1Han
jsr set_VTIMR1_handler
lda #<T2Han
ldx #>T2Han
jsr set_VTIMR2_handler
.else
lda VTIMR1
sta OldT1
lda VTIMR1+1
sta OldT1+1
lda VTIMR2
sta OldT2
lda VTIMR2+1
sta OldT2+1
php
sei
lda #<T1Han
sta VTIMR1
lda #>T1Han
sta VTIMR1+1
lda #<T2Han
sta VTIMR2
lda #>T2Han
sta VTIMR2+1
plp
.endif
@@ -257,20 +258,12 @@ INSTALL:
sta AUDCTL
lda #0
sta AUDC1
sta AUDC2
lda #15
sta AUDF1
sta AUDF2
sta STIMER
.if 0 ; the IRQ will now be dynamically enabled when the mouse is moved
lda POKMSK
ora #%00000001 ; timer 1 enable
sta POKMSK
sta IRQEN
sta irq_enabled
.endif
lda PORTA
and #$0f
sta old_porta_vbi
@@ -290,23 +283,23 @@ UNINSTALL:
; uninstall timer irq routine
lda POKMSK
and #%11111110 ; timer 1 disable
and #%11111101 ; timer 2 disable
sta IRQEN
sta POKMSK
.ifdef __ATARIXL__
clc
jsr set_VTIMR1_handler
jsr set_VTIMR2_handler
.else
php
sei
lda OldT1
sta VTIMR1
lda OldT1+1
sta VTIMR1+1
lda OldT2
sta VTIMR2
lda OldT2+1
sta VTIMR2+1
plp
.endif
@@ -503,7 +496,7 @@ IRQ: lda PORTA ; mouse port contents
; Turn mouse polling IRQ back on
lda POKMSK
ora #%00000001 ; timer 1 enable
ora #%00000010 ; timer 2 enable
sta POKMSK
sta IRQEN
sta irq_enabled
@@ -533,7 +526,7 @@ IRQ: lda PORTA ; mouse port contents
sta irq_enabled
lda POKMSK
and #%11111110 ; timer 1 disable
and #%11111101 ; timer 2 disable
sta IRQEN
sta POKMSK
@@ -620,13 +613,18 @@ IRQ: lda PORTA ; mouse port contents
;----------------------------------------------------------------------------
; T1Han: Local IRQ routine to poll mouse
; T2Han: Local IRQ routine to poll mouse
;
T1Han: lda CRITIC ; if CRITIC flag is set, disable the
T2Han: lda CRITIC ; if CRITIC flag is set, disable the
bne disable_me ; high frequency polling IRQ, in order
; not to interfere with SIO I/O (e.g.
; floppy access)
; floppy access or serial I/O)
lda in_irq ; handler entered again?
bne skip ; yes, ignore this interrupt
inc in_irq
cli ; enable IRQs so that we don't block them for too long
tya
pha
@@ -803,6 +801,8 @@ mmexit: sty oldval
tax
pla
tay
dec in_irq
skip:
.ifdef __ATARIXL__
rts
.else
@@ -819,7 +819,7 @@ mmexit: sty oldval
disable_me:
lda POKMSK
and #%11111110 ; timer 1 disable
and #%11111101 ; timer 2 disable
sta IRQEN
sta POKMSK
lda #0

View File

@@ -5,8 +5,8 @@
.export mouse_libref
.ifdef __ATARIXL__
.import set_VTIMR1_handler
mouse_libref := set_VTIMR1_handler
.import set_VTIMR2_handler
mouse_libref := set_VTIMR2_handler
.else
.import _exit
mouse_libref := _exit

View File

@@ -0,0 +1,81 @@
;
; Atari XL shadow RAM timer IRQ #2 handler
;
; Christian Groessler, chris@groessler.org, 2019
;
;DEBUG = 1
.ifdef __ATARIXL__
SHRAM_HANDLERS = 1
.include "atari.inc"
.include "romswitch.inc"
.export set_VTIMR2_handler
.segment "LOWBSS"
VTIMR2_handler: .res 3
.segment "BSS"
old_VTIMR2_handler:
.res 2
.segment "LOWCODE"
; timer interrupt handler:
; disable ROM, call user handler, enable ROM again
my_VTIMR2_handler:
disable_rom_quick
jsr VTIMR2_handler
enable_rom_quick
pla
rti
.segment "CODE"
; install or remove VTIMR2 handler
; input: CF - 0/1 for remove/install handler
; AX - pointer to handler (if CF=1)
; registers destroyed
set_VTIMR2_handler:
bcc @remove
; install vector
stx VTIMR2_handler+2
sta VTIMR2_handler+1 ; save passed vector in low memory
lda #$4C ; "JMP" opcode
sta VTIMR2_handler
lda VTIMR2
sta old_VTIMR2_handler
lda VTIMR2+1
sta old_VTIMR2_handler+1
lda #<my_VTIMR2_handler
php
sei
sta VTIMR2
lda #>my_VTIMR2_handler
sta VTIMR2+1
plp
rts
@remove: php
sei
lda old_VTIMR2_handler
sta VTIMR2
lda old_VTIMR2_handler+1
sta VTIMR2+1
plp
rts
.endif ; .ifdef __ATARIXL__

View File

@@ -16,8 +16,7 @@
;DEBUG = 1
.export __SYSTEM_CHECK__: absolute = 1
.import __SYSCHK_LOAD__
.export __SYSTEM_CHECK__, __SYSCHK_END__
.import __STARTADDRESS__
; the following imports are only needed for the 'atari' target version
@@ -25,10 +24,12 @@
.import __STACKSIZE__
.import __RESERVED_MEMORY__
; import our header and trailers
.forceimport __SYSCHKHDR__, __SYSCHKTRL__
.include "zeropage.inc"
.include "atari.inc"
.macro print_string text
.local start, cont
jmp cont
@@ -229,25 +230,10 @@ delay1: ldx #0
.endproc
end:
__SYSTEM_CHECK__=syschk
__SYSCHK_END__:
.ifndef __ATARIXL__
tmp: ; outside of the load chunk, some kind of poor man's .bss
.endif
; ------------------------------------------------------------------------
; Chunk header
.segment "SYSCHKHDR"
.word __SYSCHK_LOAD__
.word end - 1
; ------------------------------------------------------------------------
; Chunk "trailer" - sets INITAD
.segment "SYSCHKTRL"
.word INITAD
.word INITAD+1
.word syschk

View File

@@ -0,0 +1,16 @@
;
; Atari startup system check headers
;
; Christian Groessler, chris@groessler.org, 2013
;
.export __SYSCHKHDR__: absolute = 1
.import __SYSCHK_LOAD__, __SYSCHK_END__
; ------------------------------------------------------------------------
; Chunk header
.segment "SYSCHKHDR"
.word __SYSCHK_LOAD__
.word __SYSCHK_END__ - 1

View File

@@ -0,0 +1,17 @@
;
; Atari startup system check headers
;
; Christian Groessler, chris@groessler.org, 2013
;
.export __SYSCHKTRL__: absolute = 1
.import __SYSTEM_CHECK__
.include "atari.inc"
; ------------------------------------------------------------------------
; Chunk "trailer" - sets INITAD
.segment "SYSCHKTRL"
.word INITAD
.word INITAD+1
.word __SYSTEM_CHECK__

View File

@@ -22,13 +22,11 @@ static char C_dev[] = "C:";
static struct __iocb *findfreeiocb(void)
{
struct __iocb *iocb = &IOCB; /* first IOCB (#0) */
int i;
for (i = 0; i < 8; i++) {
if (iocb->handler == 0xff)
return iocb;
iocb++;
if (OS.iocb[i].handler == 0xff)
return &OS.iocb[i];
}
return NULL;
}
@@ -52,7 +50,7 @@ int main(int argc, char **argv)
fprintf(stderr, "couldn't find a free iocb\n");
return 1;
}
iocb_num = (iocb - &IOCB) * 16;
iocb_num = (iocb - OS.iocb) * 16;
if (verbose)
printf("using iocb index $%02X ($%04X)\n", iocb_num, iocb);

View File

@@ -1110,11 +1110,8 @@ skipm: ; Loop while --dy > 0
; locals
string := tmp1
cols := tmp3
pixels := tmp4
font := regsave
.rodata
ataint: .byte 64,0,32,96
.bss
rows: .res 1
@@ -1222,32 +1219,31 @@ scvert: ldx x1
.endif
; Draw one character
; Convert to ANTIC code
draw: tay
rol a
rol a
rol a
rol a
and #3
tax
tya
and #$9f
ora ataint,x
; Save and clear inverse video bit
sta inv
and #$7F
draw:
; Extract the inverse mask
ldx #0
asl a
bcc noinv
dex
noinv: stx inv
; Calculate font data address
ldx CHBAS
cmp #$20*2
bpl lowhalf
; Semigraphic or lowercase
inx
inx
lowhalf:
asl a
bcc lowquarter
; Letter
inx
lowquarter:
asl a
sta font
lda #0
sta font + 1
stx font+1
.repeat 3
asl font
rol a
.endrepeat
adc CHBAS
sta font + 1
; Save old coords
bit text_dir
bpl hor
@@ -1273,15 +1269,12 @@ cont: ldy #7
; Put one row of the glyph
putrow: sty rows
lda (font),y
bit inv
bpl noinv
eor #$FF
noinv: sta pixels
lda #7
sta cols
eor inv
sec
rol a
sta pixels
; Put one column of the row
putcol: asl pixels
bcc next_col
putcol: bcc next_col
lda x1
pha
lda x1 + 1
@@ -1317,8 +1310,8 @@ vertinc:
sub mag_x
sta y2
L2:
dec cols
bpl putcol
asl pixels
bne putcol
next_row:
; Go to next row
bit text_dir

View File

@@ -44,15 +44,15 @@
.addr $0000
; Jump table
.addr INSTALL
.addr UNINSTALL
.addr OPEN
.addr CLOSE
.addr GET
.addr PUT
.addr SER_INSTALL
.addr SER_UNINSTALL
.addr SER_OPEN
.addr SER_CLOSE
.addr SER_GET
.addr SER_PUT
.addr SER_STATUS
.addr IOCTL
.addr IRQ
.addr SER_IOCTL
.addr SER_IRQ
;----------------------------------------------------------------------------
; Global variables
@@ -116,23 +116,23 @@ ParityTable:
.code
;----------------------------------------------------------------------------
; INSTALL: Is called after the driver is loaded into memory. If possible,
; SER_INSTALL: Is called after the driver is loaded into memory. If possible,
; check if the hardware is present. Must return an SER_ERR_xx code in a/x.
;
; Since we don't have to manage the IRQ vector on the Telestrat/Atmos, this is
; actually the same as:
;
; UNINSTALL: Is called before the driver is removed from memory.
; SER_UNINSTALL: Is called before the driver is removed from memory.
; No return code required (the driver is removed from memory on return).
;
; and:
;
; CLOSE: Close the port and disable interrupts. Called without parameters.
; SER_CLOSE: Close the port and disable interrupts. Called without parameters.
; Must return an SER_ERR_xx code in a/x.
INSTALL:
UNINSTALL:
CLOSE:
SER_INSTALL:
SER_UNINSTALL:
SER_CLOSE:
ldx Index ; Check for open port
beq :+
@@ -147,10 +147,10 @@ CLOSE:
rts
;----------------------------------------------------------------------------
; OPEN: A pointer to a ser_params structure is passed in ptr1.
; SER_OPEN: A pointer to a ser_params structure is passed in ptr1.
; Must return an SER_ERR_xx code in a/x.
OPEN:
SER_OPEN:
; Check if the handshake setting is valid
ldy #SER_PARAMS::HANDSHAKE ; Handshake
lda (ptr1),y
@@ -220,11 +220,11 @@ InvBaud:lda #<SER_ERR_BAUD_UNAVAIL
rts
;----------------------------------------------------------------------------
; GET: Will fetch a character from the receive buffer and store it into the
; SER_GET: Will fetch a character from the receive buffer and store it into the
; variable pointed to by ptr1. If no data is available, SER_ERR_NO_DATA is
; returned.
GET:
SER_GET:
ldy SendFreeCnt ; Send data if necessary
iny ; Y == $FF?
beq :+
@@ -261,10 +261,10 @@ GET:
rts
;----------------------------------------------------------------------------
; PUT: Output character in A.
; SER_PUT: Output character in A.
; Must return an SER_ERR_xx code in a/x.
PUT:
SER_PUT:
; Try to send
ldy SendFreeCnt
iny ; Y = $FF?
@@ -303,22 +303,22 @@ SER_STATUS:
rts
;----------------------------------------------------------------------------
; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; specific data in ptr1, and the ioctl code in A.
; Must return an SER_ERR_xx code in a/x.
IOCTL:
SER_IOCTL:
lda #<SER_ERR_INV_IOCTL
ldx #>SER_ERR_INV_IOCTL
rts
;----------------------------------------------------------------------------
; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
; SER_IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
; registers are already saved, no parameters are passed, but the carry flag
; is clear on entry. The routine must return with carry set if the interrupt
; was handled, otherwise with carry clear.
IRQ:
SER_IRQ:
ldx Index ; Check for open port
beq Done
lda ACIA::STATUS,x ; Check ACIA status for receive interrupt

View File

@@ -10,6 +10,7 @@
.import cursor
.include "cbm_kernal.inc"
.include "c128.inc"
;--------------------------------------------------------------------------
@@ -17,8 +18,8 @@
_cgetc: lda KEY_COUNT ; Get number of characters
bne L2 ; Jump if there are already chars waiting
; Switch on the cursor if needed. We MUST always switch the cursor on,
; before switching it off, because switching it off will restore the
; Switch on the cursor if needed. We MUST always switch the cursor on,
; before switching it off, because switching it off will restore the
; character attribute remembered when it was switched on. So just switching
; it off will restore the wrong character attribute.

View File

@@ -6,9 +6,6 @@
.export _clrscr
.include "c128.inc"
.include "cbm_kernal.inc"
_clrscr = CLRSCR

View File

@@ -9,8 +9,8 @@
.export _cputcxy, _cputc, cputdirect, putchar
.export newline, plot
.import gotoxy
.import PLOT
.include "cbm_kernal.inc"
.include "c128.inc"
newline = NEWLINE
@@ -85,4 +85,3 @@ plot: ldy CURS_X
; position in Y
putchar = $CC2F

View File

@@ -25,6 +25,7 @@
.constructor initmainargs, 24
.import __argc, __argv
.include "cbm_kernal.inc"
.include "c128.inc"

View File

@@ -45,15 +45,15 @@
; Jump table
.word INSTALL
.word UNINSTALL
.word OPEN
.word CLOSE
.word GET
.word PUT
.word STATUS
.word IOCTL
.word IRQ
.word SER_INSTALL
.word SER_UNINSTALL
.word SER_OPEN
.word SER_CLOSE
.word SER_GET
.word SER_PUT
.word SER_STATUS
.word SER_IOCTL
.word SER_IRQ
;----------------------------------------------------------------------------
; I/O definitions
@@ -155,11 +155,11 @@ Vector := *+1
.reloc
;----------------------------------------------------------------------------
; INSTALL routine. Is called after the driver is loaded into memory. If
; SER_INSTALL routine. Is called after the driver is loaded into memory. If
; possible, check if the hardware is present.
; Must return an SER_ERR_xx code in a/x.
INSTALL:
SER_INSTALL:
; Deactivate DTR and disable 6551 interrupts
@@ -192,10 +192,10 @@ SetNMI: sta NMIVec
rts
;----------------------------------------------------------------------------
; UNINSTALL routine. Is called before the driver is removed from memory.
; SER_UNINSTALL routine. Is called before the driver is removed from memory.
; Must return an SER_ERR_xx code in a/x.
UNINSTALL:
SER_UNINSTALL:
; Stop interrupts, drop DTR
@@ -212,7 +212,7 @@ UNINSTALL:
; PARAMS routine. A pointer to a ser_params structure is passed in ptr1.
; Must return an SER_ERR_xx code in a/x.
OPEN:
SER_OPEN:
; Check if the handshake setting is valid
@@ -283,11 +283,11 @@ InvBaud:
rts
;----------------------------------------------------------------------------
; CLOSE: Close the port, disable interrupts and flush the buffer. Called
; SER_CLOSE: Close the port, disable interrupts and flush the buffer. Called
; without parameters. Must return an error code in a/x.
;
CLOSE:
SER_CLOSE:
; Stop interrupts, drop DTR
@@ -305,12 +305,13 @@ CLOSE:
rts
;----------------------------------------------------------------------------
; GET: Will fetch a character from the receive buffer and store it into the
; SER_GET: Will fetch a character from the receive buffer and store it into the
; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
; return.
;
GET: ldx SendFreeCnt ; Send data if necessary
SER_GET:
ldx SendFreeCnt ; Send data if necessary
inx ; X == $FF?
beq @L1
lda #$00
@@ -349,11 +350,11 @@ GET: ldx SendFreeCnt ; Send data if necessary
rts
;----------------------------------------------------------------------------
; PUT: Output character in A.
; SER_PUT: Output character in A.
; Must return an error code in a/x.
;
PUT:
SER_PUT:
; Try to send
@@ -383,23 +384,25 @@ PUT:
rts
;----------------------------------------------------------------------------
; STATUS: Return the status in the variable pointed to by ptr1.
; SER_STATUS: Return the status in the variable pointed to by ptr1.
; Must return an error code in a/x.
;
STATUS: lda ACIA_STATUS
SER_STATUS:
lda ACIA_STATUS
ldx #0
sta (ptr1,x)
txa ; SER_ERR_OK
rts
;----------------------------------------------------------------------------
; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; specific data in ptr1, and the ioctl code in A.
; Must return an error code in a/x.
;
IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
SER_IOCTL:
lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
ldx #>SER_ERR_INV_IOCTL
rts
@@ -407,7 +410,7 @@ IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
; IRQ: Not used on the C128
;
IRQ = $0000
SER_IRQ = $0000
;----------------------------------------------------------------------------
;
@@ -500,5 +503,3 @@ InitBuffers:
stx RecvFreeCnt
stx SendFreeCnt
rts

View File

@@ -7,6 +7,7 @@
.export _cgetc
.import cursor
.include "cbm_kernal.inc"
.include "plus4.inc"

View File

@@ -6,10 +6,6 @@
.export _clrscr
.include "plus4.inc"
.include "cbm_kernal.inc"
_clrscr = CLRSCR

View File

@@ -7,6 +7,7 @@
.export _cgetc
.import cursor
.include "cbm_kernal.inc"
.include "c64.inc"
_cgetc: lda KEY_COUNT ; Get number of characters

View File

@@ -6,9 +6,6 @@
.export _clrscr
.include "c64.inc"
.include "cbm_kernal.inc"
_clrscr = CLRSCR

View File

@@ -24,6 +24,7 @@
.include "zeropage.inc"
.include "ser-kernel.inc"
.include "ser-error.inc"
.include "cbm_kernal.inc"
.include "c64.inc"
.macpack module
@@ -45,15 +46,15 @@
; Jump table
.word INSTALL
.word UNINSTALL
.word OPEN
.word CLOSE
.word GET
.word PUT
.word STATUS
.word IOCTL
.word IRQ
.word SER_INSTALL
.word SER_UNINSTALL
.word SER_OPEN
.word SER_CLOSE
.word SER_GET
.word SER_PUT
.word SER_STATUS
.word SER_IOCTL
.word SER_IRQ
;----------------------------------------------------------------------------
; I/O definitions
@@ -136,11 +137,11 @@ ParityTable:
.code
;----------------------------------------------------------------------------
; INSTALL routine. Is called after the driver is loaded into memory. If
; SER_INSTALL routine. Is called after the driver is loaded into memory. If
; possible, check if the hardware is present.
; Must return an SER_ERR_xx code in a/x.
INSTALL:
SER_INSTALL:
; Deactivate DTR and disable 6551 interrupts
@@ -165,10 +166,10 @@ SetNMI: sta NMIVec
rts
;----------------------------------------------------------------------------
; UNINSTALL routine. Is called before the driver is removed from memory.
; SER_UNINSTALL routine. Is called before the driver is removed from memory.
; Must return an SER_ERR_xx code in a/x.
UNINSTALL:
SER_UNINSTALL:
; Stop interrupts, drop DTR
@@ -185,7 +186,7 @@ UNINSTALL:
; PARAMS routine. A pointer to a ser_params structure is passed in ptr1.
; Must return an SER_ERR_xx code in a/x.
OPEN:
SER_OPEN:
; Check if the handshake setting is valid
@@ -256,11 +257,11 @@ InvBaud:
rts
;----------------------------------------------------------------------------
; CLOSE: Close the port, disable interrupts and flush the buffer. Called
; SER_CLOSE: Close the port, disable interrupts and flush the buffer. Called
; without parameters. Must return an error code in a/x.
;
CLOSE:
SER_CLOSE:
; Stop interrupts, drop DTR
@@ -278,12 +279,13 @@ CLOSE:
rts
;----------------------------------------------------------------------------
; GET: Will fetch a character from the receive buffer and store it into the
; SER_GET: Will fetch a character from the receive buffer and store it into the
; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
; return.
;
GET: ldx SendFreeCnt ; Send data if necessary
SER_GET:
ldx SendFreeCnt ; Send data if necessary
inx ; X == $FF?
beq @L1
lda #$00
@@ -322,11 +324,11 @@ GET: ldx SendFreeCnt ; Send data if necessary
rts
;----------------------------------------------------------------------------
; PUT: Output character in A.
; SER_PUT: Output character in A.
; Must return an error code in a/x.
;
PUT:
SER_PUT:
; Try to send
@@ -356,31 +358,33 @@ PUT:
rts
;----------------------------------------------------------------------------
; STATUS: Return the status in the variable pointed to by ptr1.
; SER_STATUS: Return the status in the variable pointed to by ptr1.
; Must return an error code in a/x.
;
STATUS: lda ACIA_STATUS
SER_STATUS:
lda ACIA_STATUS
ldx #0
sta (ptr1,x)
txa ; SER_ERR_OK
rts
;----------------------------------------------------------------------------
; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; specific data in ptr1, and the ioctl code in A.
; Must return an error code in a/x.
;
IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
SER_IOCTL:
lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
ldx #>SER_ERR_INV_IOCTL
rts
rts
;----------------------------------------------------------------------------
; IRQ: Not used on the C64
; SER_IRQ: Not used on the C64
;
IRQ = $0000
SER_IRQ = $0000
;----------------------------------------------------------------------------
;
@@ -476,4 +480,3 @@ InitBuffers:
stx RecvFreeCnt
stx SendFreeCnt
rts

View File

@@ -11,6 +11,7 @@
.import cursor
.importzp tmp1
.include "cbm_kernal.inc"
.include "c64.inc"
.include "soft80.inc"

View File

@@ -12,6 +12,7 @@
.import cursor
.importzp tmp1
.include "cbm_kernal.inc"
.include "c64.inc"
.include "soft80.inc"

View File

@@ -46,15 +46,15 @@
; Jump table
.word INSTALL
.word UNINSTALL
.word OPEN
.word CLOSE
.word GET
.word PUT
.word STATUS
.word IOCTL
.word IRQ
.word SER_INSTALL
.word SER_UNINSTALL
.word SER_OPEN
.word SER_CLOSE
.word SER_GET
.word SER_PUT
.word SER_STATUS
.word SER_IOCTL
.word SER_IRQ
;----------------------------------------------------------------------------
;
@@ -122,24 +122,24 @@ ParityTable:
.code
;----------------------------------------------------------------------------
; INSTALL routine. Is called after the driver is loaded into memory. If
; SER_INSTALL routine. Is called after the driver is loaded into memory. If
; possible, check if the hardware is present.
; Must return an SER_ERR_xx code in a/x.
;
; Since we don't have to manage the IRQ vector on the Plus/4, this is actually
; the same as:
;
; UNINSTALL routine. Is called before the driver is removed from memory.
; SER_UNINSTALL routine. Is called before the driver is removed from memory.
; Must return an SER_ERR_xx code in a/x.
; and:
;
; CLOSE: Close the port, disable interrupts and flush the buffer. Called
; SER_CLOSE: Close the port, disable interrupts and flush the buffer. Called
; without parameters. Must return an error code in a/x.
;
INSTALL:
UNINSTALL:
CLOSE:
SER_INSTALL:
SER_UNINSTALL:
SER_CLOSE:
; Deactivate DTR and disable 6551 interrupts
@@ -156,7 +156,7 @@ CLOSE:
; PARAMS routine. A pointer to a ser_params structure is passed in ptr1.
; Must return an SER_ERR_xx code in a/x.
OPEN:
SER_OPEN:
; Check if the handshake setting is valid
@@ -236,12 +236,13 @@ InvBaud:
rts
;----------------------------------------------------------------------------
; GET: Will fetch a character from the receive buffer and store it into the
; SER_GET: Will fetch a character from the receive buffer and store it into the
; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
; return.
;
GET: ldx SendFreeCnt ; Send data if necessary
SER_GET:
ldx SendFreeCnt ; Send data if necessary
inx ; X == $FF?
beq @L1
lda #$00
@@ -280,11 +281,11 @@ GET: ldx SendFreeCnt ; Send data if necessary
rts
;----------------------------------------------------------------------------
; PUT: Output character in A.
; SER_PUT: Output character in A.
; Must return an error code in a/x.
;
PUT:
SER_PUT:
; Try to send
@@ -314,11 +315,12 @@ PUT:
rts
;----------------------------------------------------------------------------
; STATUS: Return the status in the variable pointed to by ptr1.
; SER_STATUS: Return the status in the variable pointed to by ptr1.
; Must return an error code in a/x.
;
STATUS: lda #$0F
SER_STATUS:
lda #$0F
sta IndReg
ldy #ACIA::STATUS
lda (acia),y
@@ -330,23 +332,25 @@ STATUS: lda #$0F
rts
;----------------------------------------------------------------------------
; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; specific data in ptr1, and the ioctl code in A.
; Must return an error code in a/x.
;
IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
SER_IOCTL:
lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
ldx #>SER_ERR_INV_IOCTL
rts
;----------------------------------------------------------------------------
; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
; SER_IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
; registers are already save, no parameters are passed, but the carry flag
; is clear on entry. The routine must return with carry set if the interrupt
; was handled, otherwise with carry clear.
;
IRQ: lda #$0F
SER_IRQ:
lda #$0F
sta IndReg ; Switch to the system bank
ldy #ACIA::STATUS
lda (acia),y ; Check ACIA status for receive interrupt
@@ -435,4 +439,3 @@ write: pha
lda ExecReg
sta IndReg
rts

View File

@@ -46,15 +46,15 @@
; Jump table
.word INSTALL
.word UNINSTALL
.word OPEN
.word CLOSE
.word GET
.word PUT
.word STATUS
.word IOCTL
.word IRQ
.word SER_INSTALL
.word SER_UNINSTALL
.word SER_OPEN
.word SER_CLOSE
.word SER_GET
.word SER_PUT
.word SER_STATUS
.word SER_IOCTL
.word SER_IRQ
;----------------------------------------------------------------------------
;
@@ -122,25 +122,25 @@ ParityTable:
.code
;----------------------------------------------------------------------------
; INSTALL routine. Is called after the driver is loaded into memory. If
; SER_INSTALL routine. Is called after the driver is loaded into memory. If
; possible, check if the hardware is present.
; Must return an SER_ERR_xx code in a/x.
;
; Since we don't have to manage the IRQ vector on the Plus/4, this is actually
; the same as:
;
; UNINSTALL routine. Is called before the driver is removed from memory.
; SER_UNINSTALL routine. Is called before the driver is removed from memory.
; Must return an SER_ERR_xx code in a/x.
;
; and:
;
; CLOSE: Close the port, disable interrupts and flush the buffer. Called
; SER_CLOSE: Close the port, disable interrupts and flush the buffer. Called
; without parameters. Must return an error code in a/x.
;
INSTALL:
UNINSTALL:
CLOSE:
SER_INSTALL:
SER_UNINSTALL:
SER_CLOSE:
; Deactivate DTR and disable 6551 interrupts
@@ -157,7 +157,7 @@ CLOSE:
; PARAMS routine. A pointer to a ser_params structure is passed in ptr1.
; Must return an SER_ERR_xx code in a/x.
OPEN:
SER_OPEN:
; Check if the handshake setting is valid
@@ -237,12 +237,13 @@ InvBaud:
rts
;----------------------------------------------------------------------------
; GET: Will fetch a character from the receive buffer and store it into the
; SER_GET: Will fetch a character from the receive buffer and store it into the
; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
; return.
;
GET: ldx SendFreeCnt ; Send data if necessary
SER_GET:
ldx SendFreeCnt ; Send data if necessary
inx ; X == $FF?
beq @L1
lda #$00
@@ -281,11 +282,11 @@ GET: ldx SendFreeCnt ; Send data if necessary
rts
;----------------------------------------------------------------------------
; PUT: Output character in A.
; SER_PUT: Output character in A.
; Must return an error code in a/x.
;
PUT:
SER_PUT:
; Try to send
@@ -315,11 +316,12 @@ PUT:
rts
;----------------------------------------------------------------------------
; STATUS: Return the status in the variable pointed to by ptr1.
; SER_STATUS: Return the status in the variable pointed to by ptr1.
; Must return an error code in a/x.
;
STATUS: lda #$0F
SER_STATUS:
lda #$0F
sta IndReg
ldy #ACIA::STATUS
lda (acia),y
@@ -331,23 +333,25 @@ STATUS: lda #$0F
rts
;----------------------------------------------------------------------------
; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; specific data in ptr1, and the ioctl code in A.
; Must return an error code in a/x.
;
IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
SER_IOCTL:
lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
ldx #>SER_ERR_INV_IOCTL
rts
;----------------------------------------------------------------------------
; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
; SER_IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
; registers are already save, no parameters are passed, but the carry flag
; is clear on entry. The routine must return with carry set if the interrupt
; was handled, otherwise with carry clear.
;
IRQ: lda #$0F
SER_IRQ:
lda #$0F
sta IndReg ; Switch to the system bank
ldy #ACIA::STATUS
lda (acia),y ; Check ACIA status for receive interrupt
@@ -436,4 +440,3 @@ write: pha
lda ExecReg
sta IndReg
rts

View File

@@ -3,7 +3,7 @@
;
; unsigned char getcpu (void);
;
.include "zeropage.inc"
.export _getcpu
; ---------------------------------------------------------------------------
@@ -17,6 +17,7 @@
; - carry set and 5 in A for a 65CE02
; - carry set and 6 in A for a HuC6280
; - carry clear and 7 in A for a 2a03/2a07
; - carry set and 8 in A for a 45GS02
;
; This function uses a $1A opcode which is a INA on the 816 and ignored
; (interpreted as a NOP) on a NMOS 6502. There are several CMOS versions
@@ -26,52 +27,95 @@
.p816 ; Enable 65816 instructions
_getcpu:
lda #0
inc a ; .byte $1A ; nop on nmos, inc on every cmos
cmp #1
bcc @L8
bcc @IsNMOS
; This is at least a 65C02, check for a 65CE02/4510
.byte $42,$EA ; neg on 65CE02/4510, nop #$EA on 65C02, wdm $EA on 65816
cmp #1
beq @L6
beq @HasINCA
; This is at least a 65CE02, check for 4510
lda #5 ; CPU_65CE02 constant
ldx #0 ; to make sure MAP doesn't do anything, the upper nybl of X and Z must be clear
.byte $5C ; map on 4510, aug on 65CE02 (acts like 4 byte nop)
lda #3 ; CPU_4510 constant
nop
bne @L9
cmp #5
beq @LoadXAndReturn
; It is either a 4510 (C65) or a 45GS02 (MEGA65)
; 45GS02 supports 32-bit ZP indirect, so use that to check CPU type
; without requiring a functioning MEGA65 hypervisor.
; We setup a read of $200xx, then store a different value in $xx
; and then re-read $200xx to see if it is unchanged.
; Setup 32-bit pointer to $00020000+tmp1
lda #<$020000+tmp1
sta regsave
lda #>$020000+tmp1
sta regsave+1
sta regsave+3 ; also write to upper byte of pointer to save an extra LDA #$00
lda #^$020000+tmp1
sta regsave+2
; Prefixing LDA ($nn),Z with a NOP uses 32-bit ZP pointer on 45GS02,
; but normal 16-bit ZP pointer on 4510
; (We assume Z=$00, which will be the normal case)
nop ; prefix to tell next instruction to be 32-bit ZP
.byte $b2,regsave ; LDA (regsave),Z
eor #$ff ; change the value
sta tmp1 ; store in $xx
; now try again to load it: If the same, then 45GS02, as $200xx is unchanged
nop ; prefix to tell next instruction to be 32-bit ZP
.byte $b2,regsave ; LDA (regsave),Z
cmp tmp1 ; does the loaded value match what is in $xx?
bne @Is45GS02 ; $200xx and $xx have different values, so must be a MEGA65 45GS02
@Is4510:
lda #3 ; CPU_4510 constant
ldx #0 ; load high byte of word
rts
@Is45GS02:
lda #8 ; CPU_45GS02 constant
ldx #0 ; load high byte of word
rts
; 6502 type of cpu, check for a 2a03/2a07
@L8:
@IsNMOS:
sed ; set decimal mode, no decimal mode on the 2a03/2a07
lda #9
clc
adc #1 ; $01+$09 = $10 on 6502, $01+$09 = $0A on 2a03/2a07
cld
cmp #$0a
beq @L5
beq @Is2a03
lda #0 ; CPU_6502 constant
beq @L9
@L5:
beq @LoadXAndReturn
@Is2a03:
lda #7 ; CPU_2A0x constant
bne @L9
bne @LoadXAndReturn
; 65C02 cpu type, check for HuC6280
@L4: ldx #6 ; CPU_HUC6280 constant
@CheckHuC6280:
ldx #6 ; CPU_HUC6280 constant
.byte $22,$EA ; sax nop on HuC6280 (A=$06, X=$01), nop #$EA on 65C02 (A=$01, X=$06)
bne @L9
bne @LoadXAndReturn
; Check for 65816/65802
@L6: xba ; .byte $EB, put $01 in B accu (nop on 65C02/65SC02)
@HasINCA:
xba ; .byte $EB, put $01 in B accu (nop on 65C02/65SC02)
dec a ; .byte $3A, A=$00
xba ; .byte $EB, A=$01 if 65816/65802 and A=$00 if 65C02/65SC02
inc a ; .byte $1A, A=$02 if 65816/65802 and A=$01 if 65C02/65SC02
cmp #2
beq @L9
beq @LoadXAndReturn
; check for 65SC02
@@ -82,9 +126,8 @@ _getcpu:
ldx $F7
sty $F7
cpx #$00
bne @L4
bne @CheckHuC6280
lda #4 ; CPU_65SC02 constant
@L9: ldx #0 ; Load high byte of word
@LoadXAndReturn:
ldx #0
rts

View File

@@ -0,0 +1,18 @@
;
; Scott Hutter
;
; 18.12.18
; void SetNewMode(void);
.export _SetNewMode
.include "jumptab.inc"
.include "geossym.inc"
_SetNewMode:
lda graphMode
eor #$80
sta graphMode
jmp SetNewMode

View File

@@ -1062,7 +1062,7 @@ SndSetValues:
ldx #4-1
set0: ldy SndOffsets,x
lda SndChannel+2,y
_IFNE ; flag == 0 => don`t set
_IFNE ; flag == 0 => don't set
bit #$80
_IFNE ;

View File

@@ -25,15 +25,15 @@
.addr $0000
; Jump table
.addr INSTALL
.addr UNINSTALL
.addr OPEN
.addr CLOSE
.addr GET
.addr PUT
.addr STATUS
.addr IOCTL
.addr IRQ
.addr SER_INSTALL
.addr SER_UNINSTALL
.addr SER_OPEN
.addr SER_CLOSE
.addr SER_GET
.addr SER_PUT
.addr SER_STATUS
.addr SER_IOCTL
.addr SER_IRQ
;----------------------------------------------------------------------------
; Global variables
@@ -54,25 +54,25 @@ TxDone: .res 1
.code
;----------------------------------------------------------------------------
; INSTALL: Is called after the driver is loaded into memory.
; SER_INSTALL: Is called after the driver is loaded into memory.
;
; Must return an SER_ERR_xx code in a/x.
INSTALL:
SER_INSTALL:
; Set up IRQ vector ?
;----------------------------------------------------------------------------
; UNINSTALL: Is called before the driver is removed from memory.
; SER_UNINSTALL: Is called before the driver is removed from memory.
; No return code required (the driver is removed from memory on return).
;
UNINSTALL:
SER_UNINSTALL:
;----------------------------------------------------------------------------
; CLOSE: Close the port and disable interrupts. Called without parameters.
; SER_CLOSE: Close the port and disable interrupts. Called without parameters.
; Must return an SER_ERR_xx code in a/x.
CLOSE:
SER_CLOSE:
; Disable interrupts
; Done, return an error code
lda #<SER_ERR_OK
@@ -80,7 +80,7 @@ CLOSE:
rts
;----------------------------------------------------------------------------
; OPEN: A pointer to a ser_params structure is passed in ptr1.
; SER_OPEN: A pointer to a ser_params structure is passed in ptr1.
;
; The Lynx has only two correct serial data formats:
; 8 bits, parity mark, 1 stop bit
@@ -101,7 +101,7 @@ CLOSE:
;
; Must return an SER_ERR_xx code in a/x.
OPEN:
SER_OPEN:
stz RxPtrIn
stz RxPtrOut
stz TxPtrIn
@@ -247,11 +247,11 @@ invparameter:
rts
;----------------------------------------------------------------------------
; GET: Will fetch a character from the receive buffer and store it into the
; SER_GET: Will fetch a character from the receive buffer and store it into the
; variable pointed to by ptr1. If no data is available, SER_ERR_NO_DATA is
; returned.
GET:
SER_GET:
lda RxPtrIn
cmp RxPtrOut
bne GetByte
@@ -260,7 +260,7 @@ GET:
rts
GetByte:
ldy RxPtrOut
lda RxBuffer,y
lda RxBuffer,y
inc RxPtrOut
ldx #$00
sta (ptr1,x)
@@ -268,10 +268,10 @@ GetByte:
rts
;----------------------------------------------------------------------------
; PUT: Output character in A.
; SER_PUT: Output character in A.
; Must return an SER_ERR_xx code in a/x.
PUT:
SER_PUT:
tax
lda TxPtrIn
ina
@@ -301,10 +301,10 @@ PutByte:
rts
;----------------------------------------------------------------------------
; STATUS: Return the status in the variable pointed to by ptr1.
; SER_STATUS: Return the status in the variable pointed to by ptr1.
; Must return an SER_ERR_xx code in a/x.
STATUS:
SER_STATUS:
ldy SerialStat
ldx #$00
sta (ptr1,x)
@@ -312,17 +312,17 @@ STATUS:
rts
;----------------------------------------------------------------------------
; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; specific data in ptr1, and the ioctl code in A.
; Must return an SER_ERR_xx code in a/x.
IOCTL:
SER_IOCTL:
lda #<SER_ERR_INV_IOCTL
ldx #>SER_ERR_INV_IOCTL
rts
;----------------------------------------------------------------------------
; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
; SER_IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
; registers are already saved, no parameters are passed, but the carry flag
; is clear on entry. The routine must return with carry set if the interrupt
; was handled, otherwise with carry clear.
@@ -330,7 +330,7 @@ IOCTL:
; Both the Tx and Rx interrupts are level sensitive instead of edge sensitive.
; Due to this bug you have to disable the interrupt before clearing it.
IRQ:
SER_IRQ:
lda INTSET ; Poll all pending interrupts
and #SERIAL_INTERRUPT
bne @L0
@@ -411,4 +411,3 @@ IRQ:
@IRQexit:
clc
rts

View File

@@ -7,6 +7,7 @@
.export _cgetc
.import cursor
.include "cbm_kernal.inc"
.include "plus4.inc"
; --------------------------------------------------------------------------

View File

@@ -6,6 +6,7 @@
.export _clrscr
.include "cbm_kernal.inc"
.include "plus4.inc"
.segment "LOWCODE" ; Must go into low memory
@@ -16,9 +17,3 @@
sta ENABLE_RAM ; Switch back to RAM
rts ; Return to caller
.endproc

View File

@@ -45,15 +45,15 @@
; Jump table
.word INSTALL
.word UNINSTALL
.word OPEN
.word CLOSE
.word GET
.word PUT
.word STATUS
.word IOCTL
.word IRQ
.word SER_INSTALL
.word SER_UNINSTALL
.word SER_OPEN
.word SER_CLOSE
.word SER_GET
.word SER_PUT
.word SER_STATUS
.word SER_IOCTL
.word SER_IRQ
;----------------------------------------------------------------------------
; I/O definitions
@@ -130,25 +130,25 @@ ParityTable:
.code
;----------------------------------------------------------------------------
; INSTALL routine. Is called after the driver is loaded into memory. If
; SER_INSTALL routine. Is called after the driver is loaded into memory. If
; possible, check if the hardware is present.
; Must return an SER_ERR_xx code in a/x.
;
; Since we don't have to manage the IRQ vector on the Plus/4, this is actually
; the same as:
;
; UNINSTALL routine. Is called before the driver is removed from memory.
; SER_UNINSTALL routine. Is called before the driver is removed from memory.
; Must return an SER_ERR_xx code in a/x.
;
; and:
;
; CLOSE: Close the port, disable interrupts and flush the buffer. Called
; SER_CLOSE: Close the port, disable interrupts and flush the buffer. Called
; without parameters. Must return an error code in a/x.
;
INSTALL:
UNINSTALL:
CLOSE:
SER_INSTALL:
SER_UNINSTALL:
SER_CLOSE:
; Deactivate DTR and disable 6551 interrupts
@@ -165,7 +165,7 @@ CLOSE:
; PARAMS routine. A pointer to a ser_params structure is passed in ptr1.
; Must return an SER_ERR_xx code in a/x.
OPEN:
SER_OPEN:
; Check if the handshake setting is valid
@@ -244,12 +244,13 @@ InvBaud:
rts
;----------------------------------------------------------------------------
; GET: Will fetch a character from the receive buffer and store it into the
; SER_GET: Will fetch a character from the receive buffer and store it into the
; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
; return.
;
GET: ldx SendFreeCnt ; Send data if necessary
SER_GET:
ldx SendFreeCnt ; Send data if necessary
inx ; X == $FF?
beq @L1
lda #$00
@@ -288,11 +289,11 @@ GET: ldx SendFreeCnt ; Send data if necessary
rts
;----------------------------------------------------------------------------
; PUT: Output character in A.
; SER_PUT: Output character in A.
; Must return an error code in a/x.
;
PUT:
SER_PUT:
; Try to send
@@ -322,34 +323,37 @@ PUT:
rts
;----------------------------------------------------------------------------
; STATUS: Return the status in the variable pointed to by ptr1.
; SER_STATUS: Return the status in the variable pointed to by ptr1.
; Must return an error code in a/x.
;
STATUS: lda ACIA_STATUS
SER_STATUS:
lda ACIA_STATUS
ldx #0
sta (ptr1,x)
txa ; SER_ERR_OK
rts
;----------------------------------------------------------------------------
; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; specific data in ptr1, and the ioctl code in A.
; Must return an error code in a/x.
;
IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
SER_IOCTL:
lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
ldx #>SER_ERR_INV_IOCTL
rts ; Run into IRQ instead
;----------------------------------------------------------------------------
; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
; SER_IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
; registers are already save, no parameters are passed, but the carry flag
; is clear on entry. The routine must return with carry set if the interrupt
; was handled, otherwise with carry clear.
;
IRQ: lda ACIA_STATUS ; Check ACIA status for receive interrupt
SER_IRQ:
lda ACIA_STATUS ; Check ACIA status for receive interrupt
and #$08
beq @L9 ; Jump if no ACIA interrupt (carry still clear)
lda ACIA_DATA ; Get byte from ACIA
@@ -405,5 +409,3 @@ IRQ: lda ACIA_STATUS ; Check ACIA status for receive interrupt
jmp @L0
.endproc

View File

@@ -78,7 +78,7 @@ L0: asl ptr1
; Do a subtraction. we do not have enough space to store the intermediate
; result, so we may have to do the subtraction twice.
pha
tax
cmp ptr3
lda ptr2+1
sbc ptr3+1
@@ -91,9 +91,9 @@ L0: asl ptr1
; Overflow, do the subtraction again, this time store the result
sta tmp4 ; We have the high byte already
pla
txa
sbc ptr3 ; byte 0
pha
tax
lda ptr2+1
sbc ptr3+1
sta ptr2+1 ; byte 1
@@ -102,7 +102,7 @@ L0: asl ptr1
sta tmp3 ; byte 2
inc ptr1 ; Set result bit
L1: pla
L1: txa
dey
bne L0
sta ptr2

View File

@@ -34,19 +34,19 @@ L0: asl ptr1
rol a
rol sreg+1
pha
tax
cmp ptr3
lda sreg+1
sbc ptr3+1
bcc L1
sta sreg+1
pla
txa
sbc ptr3
pha
tax
inc ptr1
L1: pla
L1: txa
dey
bne L0
sta sreg

View File

@@ -42,11 +42,11 @@ umul16x16r16m:
clc
adc ptr3
pha
tax
lda ptr3+1
adc sreg+1
sta sreg+1
pla
txa
@L1: ror sreg+1
ror a

View File

@@ -9,6 +9,7 @@
.include "zeropage.inc"
.macpack cpu
;---------------------------------------------------------------------------
; 8x16 => 24 unsigned multiplication routine. Because the overhead for a
@@ -30,9 +31,14 @@ umul8x16r16:
umul8x16r24m:
umul8x16r16m:
.if (.cpu .bitand ::CPU_ISET_65SC02)
stz ptr1+1
stz sreg
.else
ldx #0
stx ptr1+1
stx sreg
.endif
ldy #8 ; Number of bits
ldx ptr3 ; Get into register for speed

View File

@@ -2,27 +2,27 @@
; jede jede@oric.org 2017-10-01
;
.export _cgetc
.import cursor
.include "telestrat.inc"
.proc _cgetc
; this routine could be quicker if we wrote in page 2 variables,
; this routine could be quicker if we wrote in page 2 variables,
; but it's better to use telemon routine in that case, because telemon can manage 4 I/O
ldx cursor ; if cursor equal to 0, then switch off cursor
beq switchoff_cursor
ldx #$00 ; x is the first screen
BRK_TELEMON(XCSSCR) ; display cursor
jmp loop ; could be replaced by a bne/beq but 'jmp' is cleaner than a bne/beq which could expect some matters
switchoff_cursor:
switchoff_cursor:
; at this step X is equal to $00, X must be set, because it's the id of the screen (telestrat can handle 4 virtuals screen)
BRK_TELEMON(XCOSCR) ; switch off cursor
loop:
BRK_TELEMON(XCOSCR) ; switch off cursor
loop:
BRK_TELEMON XRD0 ; waits until key is pressed
bcs loop
rts
.endproc
.endproc

View File

@@ -1,16 +1,16 @@
; jede jede@oric.org 2017-01-22
.export _close
.import addysp,popax
.include "zeropage.inc"
.import addysp,popax
.include "zeropage.inc"
.include "telestrat.inc"
.include "errno.inc"
.include "fcntl.inc"
.include "fcntl.inc"
; int open (const char* name, int flags, ...); /* May take a mode argument */
.proc _close
BRK_TELEMON XCLOSE ; launch primitive ROM
BRK_TELEMON XCLOSE ; launch primitive ROM
rts
.endproc

View File

@@ -1,16 +1,16 @@
;
; jede jede@oric.org 2017-02-25
;
;
.export _clrscr
.importzp sp
.include "telestrat.inc"
.proc _clrscr
; Switch to text mode
BRK_TELEMON(XTEXT)
BRK_TELEMON(XTEXT)
lda #<SCREEN
ldy #>SCREEN
@@ -21,18 +21,18 @@
ldx #>(SCREEN+SCREEN_XSIZE*SCREEN_YSIZE)
lda #' '
BRK_TELEMON XFILLM
; reset prompt position
lda #<(SCREEN+40)
sta ADSCRL
lda #>(SCREEN+40)
sta ADSCRH
; reset display position
lda #$01
sta SCRY
lda #$00
sta SCRX
sta SCRX
rts
.endproc
.endproc

View File

@@ -2,9 +2,9 @@
; jede jede@oric.org 2017-02-25
;
.export _gotox
.import popa
.importzp sp
.include "telestrat.inc"
@@ -13,4 +13,4 @@
.proc _gotox
sta SCRX
rts
.endproc
.endproc

View File

@@ -10,4 +10,4 @@
.proc _gotoy
sta SCRY
rts
.endproc
.endproc

View File

@@ -24,28 +24,28 @@ initmainargs:
ldx #0 ; Limit the length
L0: lda BUFEDT,x
beq L3
cmp #' '
bne L1
lda #0
beq L3
beq L3
cmp #' '
bne L1
lda #0
beq L3
L1: sta name,x
inx
cpx #FNAME_LEN
cpx #FNAME_LEN
bne L0
lda #0
L3:
sta name,x
lda #0
L3:
sta name,x
inc __argc ; argc always is equal to, at least, 1
ldy #1 * 2 ; Point to second argv slot
next: lda BUFEDT,x
beq done ; End of line reached
inx
cmp #' ' ; Skip leading spaces
beq next
beq next
found: cmp #'"' ; Is the argument quoted?
beq setterm ; Jump if so
@@ -58,12 +58,12 @@ setterm:sta term ; Set end of argument marker
txa ; Get low byte
clc
adc #<BUFEDT
bcc L4
inc L5+1
adc #<BUFEDT
bcc L4
inc L5+1
L4:
sta argv,y ; argv[y]=&arg
L5:
L5:
lda #>BUFEDT
sta argv+1,y
iny
@@ -92,16 +92,16 @@ argloop:lda BUFEDT,x
lda __argc ; Get low byte of argument count
cmp #MAXARGS ; Maximum number of arguments reached?
bcc next ; Parse next one if not
bcc next ; Parse next one if not
done: lda #<argv
ldx #>argv
sta __argv
stx __argv + 1
rts
.segment "INIT"
term: .res 1
@@ -113,8 +113,8 @@ name: .res FNAME_LEN + 1
args: .res SCREEN_XSIZE * 2 - 1
param_found:
.res 1
.res 1
; char* argv[MAXARGS+1]={name};
argv:
.addr name
argv:
.addr name
.res MAXARGS * 2

View File

@@ -1,13 +1,13 @@
.export _open
.import addysp,popax
.importzp sp,tmp2,tmp3,tmp1
.include "telestrat.inc"
.include "errno.inc"
.include "fcntl.inc"
.include "fcntl.inc"
; int open (const char* name, int flags, ...); /* May take a mode argument */
.proc _open
@@ -17,8 +17,8 @@
dey ; ...checked (it generates a c compiler warning)
dey
dey
beq parmok ; Branch if parameter count ok
jsr addysp ; Fix stack, throw away unused parameters
beq parmok ; Branch if parameter count ok
jsr addysp ; Fix stack, throw away unused parameters
; Parameters ok. Pop the flags and save them into tmp3
@@ -26,8 +26,8 @@ parmok:
jsr popax ; Get flagss
sta tmp3 ; save flags
; Get the filename from stack and parse it. Bail out if is not ok
jsr popax ; Get name
ldy tmp3 ; Get flags again
BRK_TELEMON XOPEN ; launch primitive ROM
jsr popax ; Get name
ldy tmp3 ; Get flags again
BRK_TELEMON XOPEN ; launch primitive ROM
rts
.endproc

View File

@@ -8,7 +8,7 @@
.include "zeropage.inc"
.include "telestrat.inc"
;int read (int fd, void* buf, unsigned count);
.proc _read
@@ -20,22 +20,20 @@
stx PTR_READ_DEST+1
sta ptr2 ; in order to calculate nb of bytes read
stx ptr2+1 ;
; jsr popax ; fp pointer don't care in this version
lda ptr1 ;
lda ptr1 ;
ldy ptr1+1 ;
BRK_TELEMON XFREAD ; calls telemon30 routine
; compute nb of bytes read
lda PTR_READ_DEST+1
sec
sbc ptr2+1
tax
tax
lda PTR_READ_DEST
sec
sbc ptr2
; Here A and X contains number of bytes read
rts
.endproc

View File

@@ -170,7 +170,7 @@ CONTROL:
;
CLEAR:
; not done yet
BRK_TELEMON(XEFFHI)
rts
; ------------------------------------------------------------------------

View File

@@ -169,7 +169,7 @@ CONTROL:
;
CLEAR:
; not done yet
BRK_TELEMON(XEFFHI)
rts
; ------------------------------------------------------------------------

View File

@@ -2,7 +2,7 @@
; jede jede@oric.org 2017-02-25
;
.export _wherex
.importzp sp
.include "telestrat.inc"
@@ -11,4 +11,4 @@
ldx #$00
lda SCRX
rts
.endproc
.endproc

View File

@@ -1,12 +1,12 @@
;
; jede jede@oric.org 2017-02-25
;
;
.export _wherey
.include "telestrat.inc"
.proc _wherey
ldx #$00
lda SCRY
rts
.endproc
.endproc

View File

@@ -23,34 +23,34 @@
jsr popax ; get fd and discard
; if fd=0001 then it stdout
cpx #0
beq next
jmp L1
next:
cmp #1
beq L1
cpx #0
beq next
jmp L1
next:
cmp #1
beq L1
; here it's a file opened
lda ptr1
sta PTR_READ_DEST
lda ptr1+1
sta PTR_READ_DEST+1
lda ptr3
ldy ptr3+1
lda ptr1
sta PTR_READ_DEST
lda ptr1+1
sta PTR_READ_DEST+1
lda ptr3
ldy ptr3+1
BRK_TELEMON XFWRITE
; compute nb of bytes written
lda PTR_READ_DEST+1
sec
sbc ptr1+1
tax
tax
lda PTR_READ_DEST
sec
sbc ptr1
rts
L1: inc ptr2
bne L2
inc ptr2+1
@@ -63,10 +63,10 @@ L2: ldy #0
BRK_TELEMON XWR0 ; macro send char to screen (channel 0 in telemon terms)
lda #$0D ; return to the beggining of the line
BRK_TELEMON XWR0 ; macro
ldx #$0D
L3:
L3:
BRK_TELEMON XWR0 ; macro
inc ptr1
@@ -81,5 +81,3 @@ L9: lda ptr3
rts
.endproc

View File

@@ -7,6 +7,7 @@
.export _cgetc
.import cursor
.include "cbm_kernal.inc"
.include "vic20.inc"
_cgetc: lda KEY_COUNT ; Get number of characters

View File

@@ -6,9 +6,6 @@
.export _clrscr
.include "vic20.inc"
.include "cbm_kernal.inc"
_clrscr = CLRSCR