Merge branch 'master' into c1p

This commit is contained in:
Stephan Mühlstrasser
2013-11-19 20:53:17 +01:00
79 changed files with 4374 additions and 248 deletions

View File

@@ -101,11 +101,28 @@ SIO_FORMAT = $21 ;format disk (default density)
SIO_FORMATS = $22 ;1050: format medium density SIO_FORMATS = $22 ;1050: format medium density
SIO_CONFIG = $44 ;configure drive SIO_CONFIG = $44 ;configure drive
SIO_CONFIGSF = $4B ;slow/fast configure drive?? SIO_CONFIGSF = $4B ;slow/fast configure drive??
SIO_RDPERCOM = $4E ;read PERCOM block (XF551)
SIO_WRPERCOM = $4F ;write PERCOM block (XF551)
SIO_WRITE = $50 ;write sector SIO_WRITE = $50 ;write sector
SIO_READ = $52 ;read sector SIO_READ = $52 ;read sector
SIO_STAT = $53 ;get status information SIO_STAT = $53 ;get status information
SIO_VERIFY = $56 ;verify sector SIO_VERIFY = $56 ;verify sector
SIO_WRITEV = $57 ;write sector with verify SIO_WRITEV = $57 ;write sector with verify
SIO_WRITETRK = $60 ;write track (Speedy)
SIO_READTRK = $62 ;read track (Speedy)
; SIO Status Code (DSTATS)
; Input: data direction
; Bit #7 - W (write operation)
; #6 - R (read operation)
; Output: status code
; $01 (001) -- OPERATION COMPLETE (NO ERRORS)
; $8A (138) -- DEVICE TIMEOUT (DOESN'T RESPOND)
; $8B (139) -- DEVICE NAK
; $8C (140) -- SERIAL BUS INPUT FRAMING ERROR
; $8E (142) -- SERIAL BUS DATA FRAME OVERRUN ERROR
; $8F (143) -- SERIAL BUS DATA FRAME CHECKSUM ERROR
; $90 (144) -- DEVICE DONE ERROR
; Character and Key Code Equates ; Character and Key Code Equates
@@ -985,9 +1002,21 @@ CASETV = $E440 ;cassette handler vector table
DISKIV = $E450 ;vector to initialize DIO DISKIV = $E450 ;vector to initialize DIO
DSKINV = $E453 ;vector to DIO DSKINV = $E453 ;vector to DIO
.ifdef __ATARIXL__
.ifndef SHRAM_HANDLERS
.import CIO_handler, SIO_handler, SETVBV_handler
.endif
.define CIOV CIO_handler
.define SIOV SIO_handler
.define SETVBV SETVBV_handler
CIOV_org = $E456 ;vector to CIO
SIOV_org = $E459 ;vector to SIO
SETVBV_org = $E45C ;vector to set VBLANK parameters
.else
CIOV = $E456 ;vector to CIO CIOV = $E456 ;vector to CIO
SIOV = $E459 ;vector to SIO SIOV = $E459 ;vector to SIO
SETVBV = $E45C ;vector to set VBLANK parameters SETVBV = $E45C ;vector to set VBLANK parameters
.endif
SYSVBV = $E45F ;vector to process immediate VBLANK SYSVBV = $E45F ;vector to process immediate VBLANK
XITVBV = $E462 ;vector to process deferred VBLANK XITVBV = $E462 ;vector to process deferred VBLANK
SIOINV = $E465 ;vector to initialize SIO SIOINV = $E465 ;vector to initialize SIO

View File

@@ -18,21 +18,26 @@ FNAME_LEN = 16 ; maximum length of file-name
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; Zero page ; Zero page
SCRPTR := $12
BASIC_BUF := $35 BASIC_BUF := $35
CHARGOT := $E8
TXTPTR := $E9
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; Low memory ; Low memory
MODEKEY := $0209 MODEKEY := $0209
CAPSLOCK := $020C CAPSLOCK := $020C ; $7F = not locked, $FF = locked
PATTERN := $0213 PATTERN := $0213
IRQVec := $0245 IRQVec := $0245 ; "fast" interrupt vector
JOINFLAG := $025A ; 0 = don't joiu, $4A = join BASIC programs JOINFLAG := $025A ; 0 = don't joiu, $4A = join BASIC programs
VERIFYFLAG := $025B ; 0 = load, 1 = verify VERIFYFLAG := $025B ; 0 = load, 1 = verify
CURS_Y := $0268 CURS_Y := $0268
CURS_X := $0269 CURS_X := $0269
STATUS := $026A STATUS := $026A
BACKGRND := $026B
FOREGRND := $026C
TIMER3 := $0276 TIMER3 := $0276
CFILE_NAME := $027F CFILE_NAME := $027F
CFOUND_NAME := $0293 CFOUND_NAME := $0293
@@ -40,10 +45,13 @@ FILESTART := $02A9
FILEEND := $02AB FILEEND := $02AB
AUTORUN := $02AD ; $00 = only load, $C7 = autorun AUTORUN := $02AD ; $00 = only load, $C7 = autorun
LANGFLAG := $02AE ; $00 = BASIC, $80 = machine code LANGFLAG := $02AE ; $00 = BASIC, $80 = machine code
LOADERR := $02B1
KEYBUF := $02DF KEYBUF := $02DF
PARMERR := $02E0
PARAM1 := $02E1 ; & $02E2 PARAM1 := $02E1 ; & $02E2
PARAM2 := $02E3 ; & $02E4 PARAM2 := $02E3 ; & $02E4
PARAM3 := $02E5 ; & $02E6 PARAM3 := $02E5 ; & $02E6
BANGVEC := $02F5
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
@@ -92,3 +100,11 @@ POINT := $F1C8
PAPER := $F204 PAPER := $F204
INK := $F210 INK := $F210
PRINT := $F77C PRINT := $F77C
; Sound Effects
PING := $FA9F
SHOOT := $FAB5
EXPLODE := $FACB
ZAP := $FAE1
TICK := $FB14
TOCK := $FB2A

View File

@@ -6,6 +6,7 @@
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; Zero page, Commodore stuff ; Zero page, Commodore stuff
TXTPTR := $3D ; Pointer into BASIC source code
TIME := $A0 ; 60HZ clock TIME := $A0 ; 60HZ clock
FNAM_LEN := $B7 ; Length of filename FNAM_LEN := $B7 ; Length of filename
SECADR := $B9 ; Secondary address SECADR := $B9 ; Secondary address

View File

@@ -6,6 +6,7 @@
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; Zero page, Commodore stuff ; Zero page, Commodore stuff
TXTPTR := $7A ; Pointer into BASIC source code
TIME := $A0 ; 60 HZ clock TIME := $A0 ; 60 HZ clock
FNAM_LEN := $B7 ; Length of filename FNAM_LEN := $B7 ; Length of filename
SECADR := $B9 ; Secondary address SECADR := $B9 ; Secondary address

View File

@@ -3,14 +3,17 @@
; ;
; Taken from a kernal disassembly done by myself in 2000/2001. ; Taken from a kernal disassembly done by myself in 2000/2001.
; ;
; Ullrich von Bassewitz, 13.09.2001 ; 2001-09-13, Ullrich von Bassewitz
; 2013-08-26, Greg King
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
; Zeropage stuff ; Zeropage stuff
ExecReg = $00 ExecReg := $00 ; Controls execution memory bank
IndReg = $01 IndReg := $01 ; Controls indirect indexed load-store bank
TXTPTR := $85 ; Far pointer into BASIC source code
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; Screen size ; Screen size
@@ -20,8 +23,11 @@ YSIZE = 25
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
; I/O Definitions ; I/O Definitions
; Note: These numbers aren't addresses. They are offsets from the start of
; each chip's register set. They are used in the indirect indexed addressing
; mode.
; I/O $d800: VIC ; I/O $d800: VIC-II
VIC_SPR0_X = $00 VIC_SPR0_X = $00
VIC_SPR0_Y = $01 VIC_SPR0_Y = $01
@@ -63,6 +69,9 @@ VIC_CTRL2 = $16
VIC_HLINE = $12 VIC_HLINE = $12
VIC_LPEN_X = $13
VIC_LPEN_Y = $14
VIC_VIDEO_ADR = $18 VIC_VIDEO_ADR = $18
VIC_IRR = $19 ; Interrupt request register VIC_IRR = $19 ; Interrupt request register
@@ -75,7 +84,6 @@ VIC_BG_COLOR2 = $23
VIC_BG_COLOR3 = $24 VIC_BG_COLOR3 = $24
; I/O $da00: SID 6581 ; I/O $da00: SID 6581
SID_S1Lo = $00 SID_S1Lo = $00
@@ -112,7 +120,7 @@ SID_Noise = $1B
SID_Read3 = $1C SID_Read3 = $1C
; I/O $db00: CIA 6526 Inter Process Communication ; I/O $db00: CIA 6526, Inter Process Communication
; I/O $dc00: CIA 6526 ; I/O $dc00: CIA 6526
.struct CIA .struct CIA
@@ -176,7 +184,13 @@ SID_Read3 = $1C
.endstruct .endstruct
; Out video memory address ;-----------------------------------------------------------------------------
; Our video memory address
COLOR_RAM = $D400 ; System bank COLOR_RAM := $D400 ; System bank
;-----------------------------------------------------------------------------
BASIC_BUF := $FB5E ; Bank 0 location of command-line
BASIC_BUF_LEN = 162 ; Maximum length of command-line

View File

@@ -1,16 +1,19 @@
; ;
; Zeropage and I/O definitions for the CBM 610 ; Zero page variables and I/O definitions for the CBM 610
; ;
; Taken from a kernal disassembly done by myself in 1987. ; Taken from a kernal disassembly done by myself in 1987.
; ;
; Ullrich von Bassewitz, 28.09.1998 ; 1998-09-28, Ullrich von Bassewitz
; 2013-08-26, Greg King
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; Zeropage stuff ; Zeropage stuff
ExecReg = $00 ExecReg := $00 ; Controls execution memory bank
IndReg = $01 IndReg := $01 ; Controls indirect indexed load-store bank
TXTPTR := $85 ; Far pointer into BASIC source code
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; Screen size ; Screen size
@@ -29,7 +32,8 @@ YSIZE = 25
DATA .byte DATA .byte
.endstruct .endstruct
; I/O $db00: CIA 6526 Inter Process Communication
; I/O $db00: CIA 6526, Inter Process Communication
; ;
; IPCcia = $db00 ; IPCcia = $db00
@@ -68,7 +72,6 @@ YSIZE = 25
; cia = $dc00 ; cia = $dc00
; I/O $dd00: ACIA 6551 ; I/O $dd00: ACIA 6551
; ;
; acia = $dd00 ; acia = $dd00
@@ -108,3 +111,7 @@ YSIZE = 25
; tpi2 = $df00 ; tpi2 = $df00
;-----------------------------------------------------------------------------
BASIC_BUF := $FA5E ; Bank 1 location of command-line
BASIC_BUF_LEN = 162 ; Maximum length of command-line

View File

@@ -55,7 +55,7 @@
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; The EMD API version, stored in EMD_HDR::VERSION ; The EMD API version, stored in EMD_HDR::VERSION
EMD_API_VERSION = $01 EMD_API_VERSION = $02
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; The asm equivalent to the C em_copy structure ; The asm equivalent to the C em_copy structure

View File

@@ -56,7 +56,7 @@
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; The JOY API version, stored in JOY_HDR::VERSION ; The JOY API version, stored in JOY_HDR::VERSION
JOY_API_VERSION = $02 JOY_API_VERSION = $03
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; Variables ; Variables

View File

@@ -97,7 +97,7 @@
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; The mouse API version, stored in MOUSE_HDR::VERSION ; The mouse API version, stored in MOUSE_HDR::VERSION
MOUSE_API_VERSION = $03 MOUSE_API_VERSION = $04
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; Bitmapped mouse driver flags, stored in MOUSE_HDR::FLAGS. ; Bitmapped mouse driver flags, stored in MOUSE_HDR::FLAGS.

View File

@@ -7,6 +7,7 @@
; Zero page, Commodore stuff ; Zero page, Commodore stuff
MEMSIZE := $34 ; Size of memory installed MEMSIZE := $34 ; Size of memory installed
TXTPTR := $77 ; Pointer into BASIC source code
TIME := $8D ; 60HZ clock TIME := $8D ; 60HZ clock
KEY_COUNT := $9E ; Number of keys in input buffer KEY_COUNT := $9E ; Number of keys in input buffer
RVS := $9F ; Reverse flag RVS := $9F ; Reverse flag
@@ -24,6 +25,9 @@ SCR_LINELEN := $D5 ; Screen line length
CURS_Y := $D8 ; Cursor row CURS_Y := $D8 ; Cursor row
FNADR := $DA ; Pointer to file name FNADR := $DA ; Pointer to file name
BASIC_BUF := $200 ; Location of command-line
BASIC_BUF_LEN = 81 ; Maximum length of command-line
KEY_BUF := $26F ; Keyboard buffer KEY_BUF := $26F ; Keyboard buffer
;---------------------------------------------------------------------------- ;----------------------------------------------------------------------------

View File

@@ -7,6 +7,7 @@
; Zero page, Commodore stuff ; Zero page, Commodore stuff
TMPPTR := $22 ; Temporary ptr used by BASIC TMPPTR := $22 ; Temporary ptr used by BASIC
TXTPTR := $3B ; Pointer into BASIC source code
TIME := $A3 ; 60HZ clock TIME := $A3 ; 60HZ clock
FNAM_LEN := $AB ; Length of filename FNAM_LEN := $AB ; Length of filename
LFN := $AC ; Logical file number LFN := $AC ; Logical file number

View File

@@ -57,7 +57,7 @@
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; The SER API version, stored SER_HDR::VERSION ; The SER API version, stored SER_HDR::VERSION
SER_API_VERSION = $01 SER_API_VERSION = $02
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; ser_params ; ser_params

View File

@@ -77,7 +77,7 @@
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; The TGI API version, stored at TGI_HDR_VERSION ; The TGI API version, stored at TGI_HDR_VERSION
TGI_API_VERSION = $04 TGI_API_VERSION = $05
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; Bitmapped tgi driver flags, stored in TGI_HDR::VARS::FLAGS. ; Bitmapped tgi driver flags, stored in TGI_HDR::VARS::FLAGS.

View File

@@ -6,6 +6,7 @@
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; Zero page, Commodore stuff ; Zero page, Commodore stuff
TXTPTR := $7A ; Pointer into BASIC source code
TIME := $A0 ; 60HZ clock TIME := $A0 ; 60HZ clock
FNAM_LEN := $B7 ; Length of filename FNAM_LEN := $B7 ; Length of filename
SECADR := $B9 ; Secondary address SECADR := $B9 ; Secondary address

29
cfg/atari-asm.cfg Normal file
View File

@@ -0,0 +1,29 @@
FEATURES {
STARTADDRESS: default = $2E00;
}
SYMBOLS {
__EXEHDR__: type = import;
__AUTOSTART__: type = import; # force inclusion of autostart "trailer"
__STARTADDRESS__: type = export, value = %S;
}
MEMORY {
ZP: file = "", define = yes, start = $0082, size = $007E;
# file header, just $FFFF
HEADER: file = %O, start = $0000, size = $0002;
# "main program" load chunk
MAINHDR: file = %O, start = $0000, size = $0004;
RAM: file = %O, define = yes, start = %S, size = $BC20 - %S;
TRAILER: file = %O, start = $0000, size = $0006;
}
SEGMENTS {
EXEHDR: load = HEADER, type = ro, optional = yes;
MAINHDR: load = MAINHDR, type = ro, optional = yes;
CODE: load = RAM, type = ro, define = yes, optional = yes;
RODATA: load = RAM, type = ro optional = yes;
DATA: load = RAM, type = rw optional = yes;
BSS: load = RAM, type = bss, define = yes, optional = yes;
ZEROPAGE: load = ZP, type = zp;
AUTOSTRT: load = TRAILER, type = ro, optional = yes;
}

View File

@@ -1,48 +1,67 @@
FEATURES { FEATURES {
STARTADDRESS: default = $2E00; STARTADDRESS: default = $2000;
} }
SYMBOLS { SYMBOLS {
__EXEHDR__: type = import;
__SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk
__AUTOSTART__: type = import; # force inclusion of autostart "trailer"
__STACKSIZE__: type = weak, value = $0800; # 2k stack __STACKSIZE__: type = weak, value = $0800; # 2k stack
__OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay __OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay
__STARTADDRESS__: type = export, value = %S;
__RESERVED_MEMORY__: type = weak, value = $0000; __RESERVED_MEMORY__: type = weak, value = $0000;
} }
MEMORY { MEMORY {
ZP: file = "", define = yes, start = $0082, size = $007E; ZP: file = "", define = yes, start = $0082, size = $007E;
HEADER: file = %O, start = $0000, size = $0006;
RAM: file = %O, start = %S + __OVERLAYSIZE__, size = $BC20 - __STACKSIZE__ - __OVERLAYSIZE__ - %S; # file header, just $FFFF
TRAILER: file = %O, start = $0000, size = $0006; HEADER: file = %O, start = $0000, size = $0002;
OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__;
OVL2: file = "%O.2", start = %S, size = __OVERLAYSIZE__; # "system check" load chunk
OVL3: file = "%O.3", start = %S, size = __OVERLAYSIZE__; SYSCHKHDR: file = %O, start = $0000, size = $0004;
OVL4: file = "%O.4", start = %S, size = __OVERLAYSIZE__; SYSCHKCHNK: file = %O, start = $2E00, size = $0300;
OVL5: file = "%O.5", start = %S, size = __OVERLAYSIZE__; SYSCHKTRL: file = %O, start = $0000, size = $0006;
OVL6: file = "%O.6", start = %S, size = __OVERLAYSIZE__;
OVL7: file = "%O.7", start = %S, size = __OVERLAYSIZE__; # "main program" load chunk
OVL8: file = "%O.8", start = %S, size = __OVERLAYSIZE__; MAINHDR: file = %O, start = $0000, size = $0004;
OVL9: file = "%O.9", start = %S, size = __OVERLAYSIZE__; RAM: file = %O, define = yes, start = %S + __OVERLAYSIZE__,
size = $BC20 - __OVERLAYSIZE__ - __STACKSIZE__ - __RESERVED_MEMORY__ - %S;
TRAILER: file = %O, start = $0000, size = $0006;
OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__;
OVL2: file = "%O.2", start = %S, size = __OVERLAYSIZE__;
OVL3: file = "%O.3", start = %S, size = __OVERLAYSIZE__;
OVL4: file = "%O.4", start = %S, size = __OVERLAYSIZE__;
OVL5: file = "%O.5", start = %S, size = __OVERLAYSIZE__;
OVL6: file = "%O.6", start = %S, size = __OVERLAYSIZE__;
OVL7: file = "%O.7", start = %S, size = __OVERLAYSIZE__;
OVL8: file = "%O.8", start = %S, size = __OVERLAYSIZE__;
OVL9: file = "%O.9", start = %S, size = __OVERLAYSIZE__;
} }
SEGMENTS { SEGMENTS {
EXEHDR: load = HEADER, type = ro; EXEHDR: load = HEADER, type = ro;
STARTUP: load = RAM, type = ro, define = yes; SYSCHKHDR: load = SYSCHKHDR, type = ro, optional = yes;
LOWCODE: load = RAM, type = ro, define = yes, optional = yes; SYSCHK: load = SYSCHKCHNK, type = rw, define = yes, optional = yes;
INIT: load = RAM, type = ro, optional = yes; SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes;
CODE: load = RAM, type = ro, define = yes; MAINHDR: load = MAINHDR, type = ro;
RODATA: load = RAM, type = ro; STARTUP: load = RAM, type = ro, define = yes;
DATA: load = RAM, type = rw; LOWCODE: load = RAM, type = ro, define = yes, optional = yes;
ZPSAVE: load = RAM, type = bss, define = yes; INIT: load = RAM, type = ro, optional = yes;
BSS: load = RAM, type = bss, define = yes; CODE: load = RAM, type = ro, define = yes;
ZEROPAGE: load = ZP, type = zp; RODATA: load = RAM, type = ro;
EXTZP: load = ZP, type = zp, optional = yes; DATA: load = RAM, type = rw;
AUTOSTRT: load = TRAILER, type = ro; BSS: load = RAM, type = bss, define = yes;
OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes; ZEROPAGE: load = ZP, type = zp;
OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes; EXTZP: load = ZP, type = zp, optional = yes;
OVERLAY3: load = OVL3, type = ro, define = yes, optional = yes; AUTOSTRT: load = TRAILER, type = ro;
OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes; OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes;
OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes; OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes;
OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes; OVERLAY3: load = OVL3, type = ro, define = yes, optional = yes;
OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes; OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes;
OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes; OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes;
OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes; OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes;
OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes;
OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes;
OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes;
} }
FEATURES { FEATURES {
CONDES: type = constructor, CONDES: type = constructor,

View File

@@ -1,28 +1,46 @@
FEATURES { FEATURES {
STARTADDRESS: default = $2E00; STARTADDRESS: default = $2000;
} }
SYMBOLS { SYMBOLS {
__EXEHDR__: type = import;
__SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk
__AUTOSTART__: type = import; # force inclusion of autostart "trailer"
__STACKSIZE__: type = weak, value = $0800; # 2k stack __STACKSIZE__: type = weak, value = $0800; # 2k stack
__STARTADDRESS__: type = export, value = %S;
__RESERVED_MEMORY__: type = weak, value = $0000; __RESERVED_MEMORY__: type = weak, value = $0000;
} }
MEMORY { MEMORY {
ZP: file = "", define = yes, start = $0082, size = $007E; ZP: file = "", define = yes, start = $0082, size = $007E;
HEADER: file = %O, start = $0000, size = $0006;
RAM: file = %O, start = %S, size = $BC20 - __STACKSIZE__ - %S; # file header, just $FFFF
TRAILER: file = %O, start = $0000, size = $0006; HEADER: file = %O, start = $0000, size = $0002;
# "system check" load chunk
SYSCHKHDR: file = %O, start = $0000, size = $0004;
SYSCHKCHNK: file = %O, start = $2E00, size = $0300;
SYSCHKTRL: file = %O, start = $0000, size = $0006;
# "main program" load chunk
MAINHDR: file = %O, start = $0000, size = $0004;
RAM: file = %O, define = yes, start = %S, size = $BC20 - __STACKSIZE__ - __RESERVED_MEMORY__ - %S;
TRAILER: file = %O, start = $0000, size = $0006;
} }
SEGMENTS { SEGMENTS {
EXEHDR: load = HEADER, type = ro; EXEHDR: load = HEADER, type = ro;
STARTUP: load = RAM, type = ro, define = yes; SYSCHKHDR: load = SYSCHKHDR, type = ro, optional = yes;
LOWCODE: load = RAM, type = ro, define = yes, optional = yes; SYSCHK: load = SYSCHKCHNK, type = rw, define = yes, optional = yes;
INIT: load = RAM, type = ro, optional = yes; SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes;
CODE: load = RAM, type = ro, define = yes; MAINHDR: load = MAINHDR, type = ro;
RODATA: load = RAM, type = ro; STARTUP: load = RAM, type = ro, define = yes;
DATA: load = RAM, type = rw; LOWCODE: load = RAM, type = ro, define = yes, optional = yes;
BSS: load = RAM, type = bss, define = yes; INIT: load = RAM, type = ro, optional = yes;
ZEROPAGE: load = ZP, type = zp; CODE: load = RAM, type = ro, define = yes;
EXTZP: load = ZP, type = zp, optional = yes; RODATA: load = RAM, type = ro;
AUTOSTRT: load = TRAILER, type = ro; DATA: load = RAM, type = rw;
BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp;
EXTZP: load = ZP, type = zp, optional = yes;
AUTOSTRT: load = TRAILER, type = ro;
} }
FEATURES { FEATURES {
CONDES: type = constructor, CONDES: type = constructor,

View File

@@ -0,0 +1,92 @@
# This config file provides a single big upper memory block (HIDDEN_RAM).
# To achieve this, it relocates the character generator from $E000 to CHARGEN.
# The runtime library must be compiled with CHARGEN_RELOC for this config
# file to work. See libsrc/atari/Makefile.inc.
FEATURES {
STARTADDRESS: default = $2400;
}
SYMBOLS {
__EXEHDR__: type = import;
__SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk
__AUTOSTART__: type = import; # force inclusion of autostart "trailer"
__STACKSIZE__: type = weak, value = $0800; # 2k stack
__STARTADDRESS__: type = export, value = %S;
}
MEMORY {
ZP: file = "", define = yes, start = $0082, size = $007E;
# just $FFFF
HEADER: file = %O, start = $0000, size = $0002;
# "system check" load chunk
SYSCHKHDR: file = %O, start = $0000, size = $0004;
SYSCHKCHNK: file = %O, start = $2E00, size = $0300;
SYSCHKTRL: file = %O, start = $0000, size = $0006;
# "shadow RAM preparation" load chunk
SRPREPHDR: file = %O, start = $0000, size = $0004;
SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned
SRPREPTRL: file = %O, start = $0000, size = $0006;
# "main program" load chunk
MAINHDR: file = %O, start = $0000, size = $0004;
RAM: file = %O, define = yes, start = %S +
__LOWBSS_SIZE__, size = $D000 -
__STACKSIZE__ -
%S -
__LOWBSS_SIZE__;
# defines entry point into program
TRAILER: file = %O, start = $0000, size = $0006;
# address of relocated character generator
CHARGEN: file = "", define = yes, start = $D800, size = $0400;
# memory beneath the ROM
HIDDEN_RAM: file = "", define = yes, start = $DC00, size = $FFFA - $DC00;
}
SEGMENTS {
EXEHDR: load = HEADER, type = ro;
SYSCHKHDR: load = SYSCHKHDR, type = ro, optional = yes;
SYSCHK: load = SYSCHKCHNK, type = rw, define = yes, optional = yes;
SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes;
SRPREPHDR: load = SRPREPHDR, type = ro;
LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and RAM, not zero initialized
SRPREP: load = SRPREPCHNK, type = rw, define = yes;
SHADOW_RAM: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = yes;
SHADOW_RAM2: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = yes;
SRPREPTRL: load = SRPREPTRL, type = ro;
MAINHDR: load = MAINHDR, type = ro;
STARTUP: load = RAM, type = ro, define = yes;
LOWCODE: load = RAM, type = ro, define = yes, optional = yes;
INIT: load = RAM, type = ro, optional = yes;
CODE: load = RAM, type = ro, define = yes;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp;
EXTZP: load = ZP, type = zp, optional = yes;
AUTOSTRT: load = TRAILER, type = ro;
}
FEATURES {
CONDES: type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__,
segment = INIT;
CONDES: type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__,
segment = RODATA;
CONDES: type = interruptor,
label = __INTERRUPTOR_TABLE__,
count = __INTERRUPTOR_COUNT__,
segment = RODATA,
import = __CALLIRQ__;
}

View File

@@ -1,48 +1,101 @@
FEATURES { FEATURES {
STARTADDRESS: default = $2E00; STARTADDRESS: default = $2400;
} }
SYMBOLS { SYMBOLS {
__EXEHDR__: type = import;
__SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk
__AUTOSTART__: type = import; # force inclusion of autostart "trailer"
__STACKSIZE__: type = weak, value = $0800; # 2k stack __STACKSIZE__: type = weak, value = $0800; # 2k stack
__OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay __OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay
__RESERVED_MEMORY__: type = weak, value = $0000; __STARTADDRESS__: type = export, value = %S;
} }
MEMORY { MEMORY {
ZP: file = "", define = yes, start = $0082, size = $007E; ZP: file = "", define = yes, start = $0082, size = $007E;
HEADER: file = %O, start = $0000, size = $0006;
RAM: file = %O, start = %S + __OVERLAYSIZE__, size = $BC20 - __STACKSIZE__ - __OVERLAYSIZE__ - %S; # just $FFFF
TRAILER: file = %O, start = $0000, size = $0006; HEADER: file = %O, start = $0000, size = $0002;
OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__;
OVL2: file = "%O.2", start = %S, size = __OVERLAYSIZE__; # "system check" load chunk
OVL3: file = "%O.3", start = %S, size = __OVERLAYSIZE__; SYSCHKHDR: file = %O, start = $0000, size = $0004;
OVL4: file = "%O.4", start = %S, size = __OVERLAYSIZE__; SYSCHKCHNK: file = %O, start = $2E00, size = $0300;
OVL5: file = "%O.5", start = %S, size = __OVERLAYSIZE__; SYSCHKTRL: file = %O, start = $0000, size = $0006;
OVL6: file = "%O.6", start = %S, size = __OVERLAYSIZE__;
OVL7: file = "%O.7", start = %S, size = __OVERLAYSIZE__; # "shadow RAM preparation" load chunk
OVL8: file = "%O.8", start = %S, size = __OVERLAYSIZE__; SRPREPHDR: file = %O, start = $0000, size = $0004;
OVL9: file = "%O.9", start = %S, size = __OVERLAYSIZE__; SRPREPCHNK: file = %O, define = yes, start = %S + __OVERLAYSIZE__, size = $7C20 - %S - __OVERLAYSIZE__ - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned
SRPREPTRL: file = %O, start = $0000, size = $0006;
# "main program" load chunk
MAINHDR: file = %O, start = $0000, size = $0004;
RAM: file = %O, define = yes, start = %S +
__OVERLAYSIZE__ +
__LOWBSS_SIZE__, size = $D000 -
__STACKSIZE__ -
%S -
__OVERLAYSIZE__ -
__LOWBSS_SIZE__;
# defines entry point into program
TRAILER: file = %O, start = $0000, size = $0006;
# memory beneath the ROM preceeding the character generator
HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800;
# address of relocated character generator (same addess as ROM version)
CHARGEN: file = "", define = yes, start = $E000, size = $0400;
# memory beneath the ROM
HIDDEN_RAM: file = "", define = yes, start = $E400, size = $FFFA - $E400;
# overlays
OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__;
OVL2: file = "%O.2", start = %S, size = __OVERLAYSIZE__;
OVL3: file = "%O.3", start = %S, size = __OVERLAYSIZE__;
OVL4: file = "%O.4", start = %S, size = __OVERLAYSIZE__;
OVL5: file = "%O.5", start = %S, size = __OVERLAYSIZE__;
OVL6: file = "%O.6", start = %S, size = __OVERLAYSIZE__;
OVL7: file = "%O.7", start = %S, size = __OVERLAYSIZE__;
OVL8: file = "%O.8", start = %S, size = __OVERLAYSIZE__;
OVL9: file = "%O.9", start = %S, size = __OVERLAYSIZE__;
} }
SEGMENTS { SEGMENTS {
EXEHDR: load = HEADER, type = ro; EXEHDR: load = HEADER, type = ro;
STARTUP: load = RAM, type = ro, define = yes;
LOWCODE: load = RAM, type = ro, define = yes, optional = yes; SYSCHKHDR: load = SYSCHKHDR, type = ro, optional = yes;
INIT: load = RAM, type = ro, optional = yes; SYSCHK: load = SYSCHKCHNK, type = rw, define = yes, optional = yes;
CODE: load = RAM, type = ro, define = yes; SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw; SRPREPHDR: load = SRPREPHDR, type = ro;
ZPSAVE: load = RAM, type = bss, define = yes; LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and RAM, not zero initialized
BSS: load = RAM, type = bss, define = yes; SRPREP: load = SRPREPCHNK, type = rw, define = yes;
ZEROPAGE: load = ZP, type = zp; SHADOW_RAM: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = yes;
EXTZP: load = ZP, type = zp, optional = yes; SHADOW_RAM2: load = SRPREPCHNK, run = HIDDEN_RAM2, type = rw, define = yes, optional = yes;
AUTOSTRT: load = TRAILER, type = ro; SRPREPTRL: load = SRPREPTRL, type = ro;
OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes;
OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes; MAINHDR: load = MAINHDR, type = ro;
OVERLAY3: load = OVL3, type = ro, define = yes, optional = yes; STARTUP: load = RAM, type = ro, define = yes;
OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes; LOWCODE: load = RAM, type = ro, define = yes, optional = yes;
OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes; INIT: load = RAM, type = ro, optional = yes;
OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes; CODE: load = RAM, type = ro, define = yes;
OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes; RODATA: load = RAM, type = ro;
OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes; DATA: load = RAM, type = rw;
OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes; BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp;
EXTZP: load = ZP, type = zp, optional = yes;
AUTOSTRT: load = TRAILER, type = ro;
OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes;
OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes;
OVERLAY3: load = OVL3, type = ro, define = yes, optional = yes;
OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes;
OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes;
OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes;
OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes;
OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes;
OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes;
} }
FEATURES { FEATURES {
CONDES: type = constructor, CONDES: type = constructor,

View File

@@ -1,28 +1,77 @@
FEATURES { FEATURES {
STARTADDRESS: default = $2E00; STARTADDRESS: default = $2400;
} }
SYMBOLS { SYMBOLS {
__EXEHDR__: type = import;
__SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk
__AUTOSTART__: type = import; # force inclusion of autostart "trailer"
__STACKSIZE__: type = weak, value = $0800; # 2k stack __STACKSIZE__: type = weak, value = $0800; # 2k stack
__RESERVED_MEMORY__: type = weak, value = $0000; __STARTADDRESS__: type = export, value = %S;
} }
MEMORY { MEMORY {
ZP: file = "", define = yes, start = $0082, size = $007E; ZP: file = "", define = yes, start = $0082, size = $007E;
HEADER: file = %O, start = $0000, size = $0006;
RAM: file = %O, start = %S, size = $BC20 - __STACKSIZE__ - %S; # just $FFFF
TRAILER: file = %O, start = $0000, size = $0006; HEADER: file = %O, start = $0000, size = $0002;
# "system check" load chunk
SYSCHKHDR: file = %O, start = $0000, size = $0004;
SYSCHKCHNK: file = %O, start = $2E00, size = $0300;
SYSCHKTRL: file = %O, start = $0000, size = $0006;
# "shadow RAM preparation" load chunk
SRPREPHDR: file = %O, start = $0000, size = $0004;
SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned
SRPREPTRL: file = %O, start = $0000, size = $0006;
# "main program" load chunk
MAINHDR: file = %O, start = $0000, size = $0004;
RAM: file = %O, define = yes, start = %S +
__LOWBSS_SIZE__, size = $D000 -
__STACKSIZE__ -
%S -
__LOWBSS_SIZE__;
# defines entry point into program
TRAILER: file = %O, start = $0000, size = $0006;
# memory beneath the ROM preceeding the character generator
HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800;
# address of relocated character generator (same addess as ROM version)
CHARGEN: file = "", define = yes, start = $E000, size = $0400;
# memory beneath the ROM
HIDDEN_RAM: file = "", define = yes, start = $E400, size = $FFFA - $E400;
} }
SEGMENTS { SEGMENTS {
EXEHDR: load = HEADER, type = ro; EXEHDR: load = HEADER, type = ro;
STARTUP: load = RAM, type = ro, define = yes;
LOWCODE: load = RAM, type = ro, define = yes, optional = yes; SYSCHKHDR: load = SYSCHKHDR, type = ro, optional = yes;
INIT: load = RAM, type = ro, optional = yes; SYSCHK: load = SYSCHKCHNK, type = rw, define = yes, optional = yes;
CODE: load = RAM, type = ro, define = yes; SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw; SRPREPHDR: load = SRPREPHDR, type = ro;
BSS: load = RAM, type = bss, define = yes; LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and RAM, not zero initialized
ZEROPAGE: load = ZP, type = zp; SRPREP: load = SRPREPCHNK, type = rw, define = yes;
EXTZP: load = ZP, type = zp, optional = yes; SHADOW_RAM: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = yes;
AUTOSTRT: load = TRAILER, type = ro; SHADOW_RAM2: load = SRPREPCHNK, run = HIDDEN_RAM2, type = rw, define = yes, optional = yes;
SRPREPTRL: load = SRPREPTRL, type = ro;
MAINHDR: load = MAINHDR, type = ro;
STARTUP: load = RAM, type = ro, define = yes;
LOWCODE: load = RAM, type = ro, define = yes, optional = yes;
INIT: load = RAM, type = ro, optional = yes;
CODE: load = RAM, type = ro, define = yes;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp;
EXTZP: load = ZP, type = zp, optional = yes;
AUTOSTRT: load = TRAILER, type = ro;
} }
FEATURES { FEATURES {
CONDES: type = constructor, CONDES: type = constructor,

View File

@@ -32,7 +32,7 @@ MEMORY {
} }
SEGMENTS { SEGMENTS {
ZEROPAGE: type = zp, load = ZP; ZEROPAGE: type = zp, load = ZP;
EXTZP: type = zp, load = ZP; EXTZP: type = zp, load = ZP, optional = yes;
EXTBSS: type = bss, load = EXT, define = yes, optional = yes; EXTBSS: type = bss, load = EXT, define = yes, optional = yes;
FILEINFO: type = ro, load = CVT, offset = $002; FILEINFO: type = ro, load = CVT, offset = $002;
RECORDS: type = ro, load = CVT, offset = $100, optional = yes; RECORDS: type = ro, load = CVT, offset = $100, optional = yes;

View File

@@ -31,7 +31,7 @@ MEMORY {
} }
SEGMENTS { SEGMENTS {
ZEROPAGE: type = zp, load = ZP; ZEROPAGE: type = zp, load = ZP;
EXTZP: type = zp, load = ZP; EXTZP: type = zp, load = ZP, optional = yes;
DIRENTRY: type = ro, load = CVT, align = $FE; DIRENTRY: type = ro, load = CVT, align = $FE;
FILEINFO: type = ro, load = CVT, align = $FE; FILEINFO: type = ro, load = CVT, align = $FE;
RECORDS: type = ro, load = CVT, align = $FE, optional = yes; RECORDS: type = ro, load = CVT, align = $FE, optional = yes;

View File

@@ -136,10 +136,22 @@ extern unsigned char _dos_type;
/* The file stream implementation and the POSIX I/O functions will use the /* The file stream implementation and the POSIX I/O functions will use the
* following variables to determine the file type and the aux type to use. * following variables to determine the file type, aux type and creation time
* stamp to use.
*/ */
extern unsigned char _filetype; /* Default 6 */ extern unsigned char _filetype; /* Default: 6 */
extern unsigned int _auxtype; /* Default 0 */ extern unsigned int _auxtype; /* Default: 0 */
extern struct {
struct {
unsigned day :5;
unsigned mon :4;
unsigned year :7;
} createdate; /* Current date: 0 */
struct {
unsigned char min;
unsigned char hour;
} createtime; /* Current time: 0 */
} _datetime;
/* The addresses of the static drivers */ /* The addresses of the static drivers */
#if !defined(__APPLE2ENH__) #if !defined(__APPLE2ENH__)

View File

@@ -131,6 +131,24 @@
#define COLOR_LIGHTBLUE _gtia_mkcolor(HUE_BLUE,6) #define COLOR_LIGHTBLUE _gtia_mkcolor(HUE_BLUE,6)
#define COLOR_GRAY3 _gtia_mkcolor(HUE_GREY,5) #define COLOR_GRAY3 _gtia_mkcolor(HUE_GREY,5)
/* TGI color defines */
#define TGI_COLOR_BLACK COLOR_BLACK
#define TGI_COLOR_WHITE COLOR_WHITE
#define TGI_COLOR_RED COLOR_RED
#define TGI_COLOR_CYAN COLOR_CYAN
#define TGI_COLOR_VIOLET COLOR_VIOLET
#define TGI_COLOR_GREEN COLOR_GREEN
#define TGI_COLOR_BLUE COLOR_BLUE
#define TGI_COLOR_YELLOW COLOR_YELLOW
#define TGI_COLOR_ORANGE COLOR_ORANGE
#define TGI_COLOR_BROWN COLOR_BROWN
#define TGI_COLOR_LIGHTRED COLOR_LIGHTRED
#define TGI_COLOR_GRAY1 COLOR_GRAY1
#define TGI_COLOR_GRAY2 COLOR_GRAY2
#define TGI_COLOR_LIGHTGREEN COLOR_LIGHTGREEN
#define TGI_COLOR_LIGHTBLUE COLOR_LIGHTBLUE
#define TGI_COLOR_GRAY3 COLOR_GRAY3
/* color register functions */ /* color register functions */
extern void __fastcall__ _setcolor (unsigned char color_reg, unsigned char hue, unsigned char luminace); extern void __fastcall__ _setcolor (unsigned char color_reg, unsigned char hue, unsigned char luminace);
extern void __fastcall__ _setcolor_low (unsigned char color_reg, unsigned char color_value); extern void __fastcall__ _setcolor_low (unsigned char color_reg, unsigned char color_value);
@@ -268,5 +286,30 @@ struct __iocb {
#define ZIOCB (*(struct __iocb *)0x20) /* zero page IOCB */ #define ZIOCB (*(struct __iocb *)0x20) /* zero page IOCB */
#define IOCB (*(struct __iocb *)0x340) /* system IOCB buffers */ #define IOCB (*(struct __iocb *)0x340) /* system IOCB buffers */
/* IOCB Command Codes */
#define IOCB_OPEN 0x03 /* open */
#define IOCB_GETREC 0x05 /* get record */
#define IOCB_GETCHR 0x07 /* get character(s) */
#define IOCB_PUTREC 0x09 /* put record */
#define IOCB_PUTCHR 0x0B /* put character(s) */
#define IOCB_CLOSE 0x0C /* close */
#define IOCB_STATIS 0x0D /* status */
#define IOCB_SPECIL 0x0E /* special */
#define IOCB_DRAWLN 0x11 /* draw line */
#define IOCB_FILLIN 0x12 /* draw line with right fill */
#define IOCB_RENAME 0x20 /* rename disk file */
#define IOCB_DELETE 0x21 /* delete disk file */
#define IOCB_LOCKFL 0x23 /* lock file (set to read-only) */
#define IOCB_UNLOCK 0x24 /* unlock file */
#define IOCB_POINT 0x25 /* point sector */
#define IOCB_NOTE 0x26 /* note sector */
#define IOCB_GETFL 0x27 /* get file length */
#define IOCB_CHDIR_MYDOS 0x29 /* change directory (MyDOS) */
#define IOCB_MKDIR 0x2A /* make directory (MyDOS/SpartaDOS) */
#define IOCB_RMDIR 0x2B /* remove directory (SpartaDOS) */
#define IOCB_CHDIR_SPDOS 0x2C /* change directory (SpartaDOS) */
#define IOCB_GETCWD 0x30 /* get current directory (MyDOS/SpartaDOS) */
#define IOCB_FORMAT 0xFE /* format */
/* End of atari.h */ /* End of atari.h */
#endif /* #ifndef _ATARI_H */ #endif /* #ifndef _ATARI_H */

View File

@@ -126,12 +126,36 @@ extern void atmos_240_200_2_tgi[]; /* Referred to by tgi_static_stddrv[] */
/*****************************************************************************/
/* Functions */
/*****************************************************************************/
void __fastcall__ atmos_load(const char* name); void __fastcall__ atmos_load(const char* name);
/* Load Atmos tape. */ /* Load Atmos tape. */
void __fastcall__ atmos_save(const char* name, const void* start, const void* end); void __fastcall__ atmos_save(const char* name, const void* start, const void* end);
/* Save Atmos tape. */ /* Save Atmos tape. */
void atmos_explode (void);
/* Bomb sound effect */
void atmos_ping (void);
/* Bell or ricochet sound effect */
void atmos_shoot (void);
/* Pistol sound effect */
void atmos_tick (void);
/* High-pitch click */
void atmos_tock (void);
/* Low-pitch click */
void atmos_zap (void);
/* Raygun sound effect */
/* End of atmos.h */ /* End of atmos.h */

View File

@@ -2,11 +2,11 @@
/* */ /* */
/* cbm510.h */ /* cbm510.h */
/* */ /* */
/* System specific definitions for the CBM5x0 / P500 */ /* System-specific definitions for the CBM5x0 / P500 */
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2001-2009, Ullrich von Bassewitz */ /* (C) 2001-2013, Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@@ -100,7 +100,7 @@
#define SID (*(struct __sid*)0xDA00) #define SID (*(struct __sid*)0xDA00)
#include <_6526.h> #include <_6526.h>
#define CIA (*(struct __6526*)0xDC00) #define CIA2 (*(struct __6526*)0xDC00)
#include <_6551.h> #include <_6551.h>
#define ACIA (*(struct __6551*)0xDD00) #define ACIA (*(struct __6551*)0xDD00)
@@ -118,6 +118,8 @@
/* The addresses of the static drivers */ /* The addresses of the static drivers */
extern void cbm510_inkwl_mou[];
extern void cbm510_joy_mou[]; /* Referred to by mouse_static_stddrv[] */
extern void cbm510_ram_emd[]; extern void cbm510_ram_emd[];
extern void cbm510_std_joy[]; /* Referred to by joy_static_stddrv[] */ extern void cbm510_std_joy[]; /* Referred to by joy_static_stddrv[] */
extern void cbm510_std_ser[]; extern void cbm510_std_ser[];

View File

@@ -5,7 +5,7 @@
; ;
.export _open, closedirect, freebuffer .export _open, closedirect, freebuffer
.export __filetype, __auxtype .export __filetype, __auxtype, __datetime
.constructor raisefilelevel .constructor raisefilelevel
.destructor closeallfiles, 5 .destructor closeallfiles, 5
@@ -246,5 +246,6 @@ __filetype:
__auxtype: __auxtype:
.word $0000 ; AUX_TYPE: Load address N/A .word $0000 ; AUX_TYPE: Load address N/A
.byte $01 ; STORAGE_TYPE: Standard seedling file .byte $01 ; STORAGE_TYPE: Standard seedling file
__datetime:
.word $0000 ; CREATE_DATE: Current date .word $0000 ; CREATE_DATE: Current date
.word $0000 ; CREATE_TIME: Current time .word $0000 ; CREATE_TIME: Current time

View File

@@ -14,3 +14,20 @@
# needs DEFAULT_DEVICE to be defined, otherwise no effect # needs DEFAULT_DEVICE to be defined, otherwise no effect
CA65FLAGS += -D NUMDRVS=4 -D LINEBUF=80 -D UCASE_FILENAME=1 -D DEFAULT_DEVICE=1 -D DYNAMIC_DD=1 CA65FLAGS += -D NUMDRVS=4 -D LINEBUF=80 -D UCASE_FILENAME=1 -D DEFAULT_DEVICE=1 -D DYNAMIC_DD=1
# The following defines are only used by the 'atarixl' target:
#
# CHARGEN_RELOC - If defined, CHBAS and CHBASE are updated when
# enabling or disabling the ROM.
# If the ROM is enabled, $E0 is written to CHBAS
# and CHBASE.
# If the ROM is disabled, the upper byte of
# __CHARGEN_START__ is written to CHBAS and CHBASE.
# USEWSYNC - If defined, the code waits for horizontal retrace
# before switching the ROM and updating CHBAS and
# CHBASE. This define only has effect if CHARGEN_RELOC
# is also defined.
# Disabled by default, you should enable it if the linker script relocates the
# character generator (like atarixl-largehimem.cfg).
#CA65FLAGS += -D CHARGEN_RELOC -D USEWSYNC

13
libsrc/atari/_sys.s Normal file
View File

@@ -0,0 +1,13 @@
;
; Christian Groessler, 17-Sep-2013
;
; Override _sys() function for Atari targets:
; 'atari' gets the regular function
; 'atarixl' doesn't support the _sys() function
;
.ifndef __ATARIXL__
.include "../common/_sys.s"
.endif

View File

@@ -7,22 +7,28 @@
.include "atari.inc" .include "atari.inc"
.export _cgetc,setcursor .export _cgetc,setcursor
.import KEYBDV_handler
.import cursor,mul40 .import cursor,mul40
_cgetc: _cgetc:
jsr setcursor jsr setcursor
lda #12
sta ICAX1Z ; fix problems with direct call to KEYBDV
.ifndef __ATARIXL__
jsr @1 jsr @1
.else
jsr KEYBDV_handler
.endif
ldx #0 ldx #0
rts rts
.ifndef __ATARIXL__
@1: lda KEYBDV+5 @1: lda KEYBDV+5
pha pha
lda KEYBDV+4 lda KEYBDV+4
pha pha
lda #12
sta ICAX1Z ; fix problems with direct call to KEYBDV
rts rts
.endif
.proc setcursor .proc setcursor

View File

@@ -8,28 +8,26 @@
; Stefan Haubenthal ; Stefan Haubenthal
; ;
.export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup .export __STARTUP__ : absolute = 1 ; Mark as startup
.export _exit, start
.import initlib, donelib .import initlib, donelib
.import callmain, zerobss .import callmain, zerobss
.import __STARTUP_LOAD__, __BSS_LOAD__
.import __RESERVED_MEMORY__ .import __RESERVED_MEMORY__
.import __RAM_START__, __RAM_SIZE__
.ifdef __ATARIXL__
.import __STACKSIZE__
.import sram_init
.import scrdev
.import findfreeiocb
.forceimport sramprep ; force inclusion of the "shadow RAM preparation" load chunk
.include "save_area.inc"
.endif
.include "zeropage.inc" .include "zeropage.inc"
.include "atari.inc" .include "atari.inc"
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; EXE header
.segment "EXEHDR"
.word $FFFF
.word __STARTUP_LOAD__
.word __BSS_LOAD__ - 1
; ------------------------------------------------------------------------
; Actual code
.segment "STARTUP" .segment "STARTUP"
@@ -40,6 +38,12 @@
; Real entry point: ; Real entry point:
start:
.ifdef __ATARIXL__
jsr sram_init
.endif
; Clear the BSS data ; Clear the BSS data
jsr zerobss jsr zerobss
@@ -47,14 +51,16 @@
; Setup the stack ; Setup the stack
tsx tsx
stx spsave stx SP_save
.ifndef __ATARIXL__
; Report memory usage ; Report memory usage
lda APPMHI lda APPMHI
sta appmsav ; remember old APPMHI value sta APPMHI_save ; remember old APPMHI value
lda APPMHI+1 lda APPMHI+1
sta appmsav+1 sta APPMHI_save+1
sec sec
lda MEMTOP lda MEMTOP
@@ -66,6 +72,15 @@
sta APPMHI+1 sta APPMHI+1
sta sp+1 ; setup runtime stack part 2 sta sp+1 ; setup runtime stack part 2
.else
lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp
lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp+1
.endif
; Call module constructors ; Call module constructors
jsr initlib jsr initlib
@@ -73,14 +88,14 @@
; Set left margin to 0 ; Set left margin to 0
lda LMARGN lda LMARGN
sta old_lmargin sta LMARGN_save
ldy #0 ldy #0
sty LMARGN sty LMARGN
; Set keyb to upper/lowercase mode ; Set keyb to upper/lowercase mode
ldx SHFLOK ldx SHFLOK
stx old_shflok stx SHFLOK_save
sty SHFLOK sty SHFLOK
; Initialize conio stuff ; Initialize conio stuff
@@ -98,26 +113,71 @@ _exit: jsr donelib ; Run module destructors
; Restore system stuff ; Restore system stuff
ldx spsave ldx SP_save
txs ; Restore stack pointer txs ; Restore stack pointer
; Restore left margin ; Restore left margin
lda old_lmargin lda LMARGN_save
sta LMARGN sta LMARGN
; Restore kb mode ; Restore kb mode
lda old_shflok lda SHFLOK_save
sta SHFLOK sta SHFLOK
; Restore APPMHI ; Restore APPMHI
lda appmsav lda APPMHI_save
sta APPMHI sta APPMHI
lda appmsav+1 lda APPMHI_save+1
sta APPMHI+1 sta APPMHI+1
.ifdef __ATARIXL__
; Atari XL target stuff...
lda PORTB_save
sta PORTB
lda RAMTOP_save
sta RAMTOP
lda MEMTOP_save
sta MEMTOP
lda MEMTOP_save+1
sta MEMTOP+1
; Issue a GRAPHICS 0 call (copied'n'pasted from TGI drivers) in
; order to restore screen memory to its defailt location just
; before the ROM.
jsr findfreeiocb
; Reopen it in Graphics 0
lda #OPEN
sta ICCOM,x
lda #OPNIN | OPNOT
sta ICAX1,x
lda #0
sta ICAX2,x
lda #<scrdev
sta ICBAL,x
lda #>scrdev
sta ICBAH,x
lda #3
sta ICBLL,x
lda #0
sta ICBLH,x
jsr CIOV_org
; No error checking here, shouldn't happen(tm), and no way to
; recover anyway.
lda #CLOSE
sta ICCOM,x
jsr CIOV_org
.endif
; Turn on cursor ; Turn on cursor
ldx #0 ldx #0
@@ -133,13 +193,9 @@ _exit: jsr donelib ; Run module destructors
.bss .bss
spsave: .res 1 SP_save: .res 1
appmsav: .res 1 SHFLOK_save: .res 1
old_shflok: .res 1 LMARGN_save: .res 1
old_lmargin: .res 1 .ifndef __ATARIXL__
APPMHI_save: .res 2
.endif
.segment "AUTOSTRT"
.word RUNAD ; defined in atari.inc
.word RUNAD+1
.word __STARTUP_LOAD__ + 1

11
libsrc/atari/exehdr.s Normal file
View File

@@ -0,0 +1,11 @@
; This file defines the EXE header and main chunk load header for Atari executables
.export __EXEHDR__: absolute = 1
.import __RAM_START__, __BSS_LOAD__
.segment "EXEHDR"
.word $FFFF
.segment "MAINHDR"
.word __RAM_START__
.word __BSS_LOAD__ - 1

12
libsrc/atari/exetrailer.s Normal file
View File

@@ -0,0 +1,12 @@
; This file defines the EXE file "trailer" which sets the entry point
.export __AUTOSTART__: absolute = 1
.import start
.include "atari.inc"
.segment "AUTOSTRT"
.word RUNAD ; defined in atari.inc
.word RUNAD+1
.word start

View File

@@ -15,6 +15,7 @@
.import clriocb .import clriocb
.import fdtoiocb .import fdtoiocb
.import newfd .import newfd
.import scrdev
.importzp tmp1,tmp2,tmp3 .importzp tmp1,tmp2,tmp3
.include "atari.inc" .include "atari.inc"
@@ -105,8 +106,3 @@ cioerr: sty tmp3 ; remember error code
jmp __mappederrno jmp __mappederrno
.endproc ; __graphics .endproc ; __graphics
.rodata
scrdev: .byte "S:", 0

View File

@@ -6,6 +6,10 @@
.import callirq .import callirq
.include "atari.inc" .include "atari.inc"
.ifdef __ATARIXL__
.import __CHARGEN_START__
.include "romswitch.inc"
.endif
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
@@ -39,7 +43,29 @@ doneirq:
IRQStub: IRQStub:
cld ; Just to be sure cld ; Just to be sure
.ifdef __ATARIXL__
pha
.ifdef CHARGEN_RELOC
lda CHBAS
pha
.endif
lda PORTB
pha
and #$FE
sta PORTB ; disable ROM
set_chbase >__CHARGEN_START__
.endif
jsr callirq ; Call the functions jsr callirq ; Call the functions
.ifdef __ATARIXL__
pla
sta PORTB ; restore old ROM setting
.ifdef CHARGEN_RELOC
pla
sta CHBAS
sta CHBASE
.endif
pla
.endif
jmp IRQInd ; Jump to the saved IRQ vector jmp IRQInd ; Jump to the saved IRQ vector
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------

View File

@@ -7,4 +7,9 @@
em_libref := _exit em_libref := _exit
joy_libref := _exit joy_libref := _exit
.ifdef __ATARIXL__
.import CIO_handler
tgi_libref := CIO_handler
.else
tgi_libref := _exit tgi_libref := _exit
.endif

View File

@@ -40,8 +40,40 @@
.export _get_ostype .export _get_ostype
.proc _get_ostype .include "atari.inc"
.include "romswitch.inc"
.ifdef __ATARIXL__
.import __CHARGEN_START__
.segment "LOWCODE"
.macro disable_rom_save_a
pha
disable_rom
pla
.endmacro
.else ; above atarixl, below atari
.macro disable_rom_save_a
.endmacro
.endif ; .ifdef __ATARIXL__
; unknown ROM
_unknown:
lda #0
tax
disable_rom_save_a
rts
_get_ostype:
enable_rom
lda $fcd8 lda $fcd8
cmp #$a2 cmp #$a2
beq _400800 beq _400800
@@ -63,13 +95,7 @@
and #%00111000 and #%00111000
ora #%11 ora #%11
_fin: ldx #0 _fin: ldx #0
rts disable_rom_save_a
; unknown ROM
_unknown:
lda #0
tax
rts rts
; 1200XL ROM ; 1200XL ROM
@@ -148,5 +174,3 @@ _400800_3:
lda #%00010001 lda #%00010001
bne _fin bne _fin
.endproc

101
libsrc/atari/romswitch.inc Normal file
View File

@@ -0,0 +1,101 @@
;
; Macros to disable and enable the ROM on Atari XL systems.
;
; Christian Groessler, chris@groessler.org, 19-Sep-2013
;
;
; Defines which modify the operation of the macros:
;
; CHARGEN_RELOC: If defined, CHBAS and CHBASE are updated when
; enabling or disabling the ROM.
; If the ROM is enabled, $E0 is written to CHBAS
; and CHBASE.
; If the ROM is disabled, the upper byte of
; __CHARGEN_START__ is written to CHBAS and CHBASE.
; USEWSYNC: If defined, the code waits for horizontal retrace
; before switching the ROM and updating CHBAS and
; CHBASE. This define only has effect if CHARGEN_RELOC
; is also defined.
.ifdef __ATARIXL__
.ifdef CHARGEN_RELOC
.macro set_chbase val
lda #val
sta CHBAS
sta CHBASE
.endmacro
.else ; above CHARGEN_RELOC, below not
.macro set_chbase val
.endmacro
.endif ; .ifdef CHARGEN_RELOC
.if .defined(USEWSYNC) .and .defined(CHARGEN_RELOC)
.macro wsync
sta WSYNC
.endmacro
.else ; above USEWSYNC, below not
.macro wsync
.endmacro
.endif
; "disable ROM" macros
.macro disable_rom
lda PORTB
and #$fe
wsync
sta PORTB
set_chbase >__CHARGEN_START__
.endmacro
.macro disable_rom_quick
lda PORTB
and #$fe
sta PORTB
set_chbase >__CHARGEN_START__
.endmacro
.macro disable_rom_val val
lda val
wsync
sta PORTB
set_chbase >__CHARGEN_START__
.endmacro
; "enable ROM" macros
.macro enable_rom
lda PORTB
ora #1
wsync
sta PORTB
set_chbase $E0
.endmacro
.macro enable_rom_quick
lda PORTB
ora #1
sta PORTB
set_chbase $E0
.endmacro
.else ; above __ATARIXL__, below not
.macro disable_rom
.endmacro
.macro enable_rom
.endmacro
.endif

View File

@@ -0,0 +1,13 @@
;
; Atari XL, shared data between 2nd load chunk and main chunk, header file
;
; Contains old values of modified system variables and ports.
;
; Christian Groessler, chris@groessler.org, 2013
;
.import SAVMSC_save
.import MEMTOP_save
.import APPMHI_save
.import RAMTOP_save
.import PORTB_save

25
libsrc/atari/save_area.s Normal file
View File

@@ -0,0 +1,25 @@
;
; Atari XL, shared data between 2nd load chunk and main chunk, definition file
;
; Contains old values of modified system variables and ports.
;
; Christian Groessler, chris@groessler.org, 2013
;
.ifdef __ATARIXL__
.export SAVMSC_save
.export MEMTOP_save
.export APPMHI_save
.export RAMTOP_save
.export PORTB_save
.segment "LOWBSS"
SAVMSC_save: .res 2
MEMTOP_save: .res 2
APPMHI_save: .res 2
RAMTOP_save: .res 1
PORTB_save: .res 1
.endif

7
libsrc/atari/scrdev.s Normal file
View File

@@ -0,0 +1,7 @@
; Name of the "screen" device
.export scrdev
.rodata
scrdev: .byte "S:", 0

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,408 @@
;
; Atari XL shadow RAM preparation routines
;
; Tasks:
; - move screen memory below load address
; - copy ROM chargen to its new place
; - copy shadow RAM contents to their destination
;
; Christian Groessler, chris@groessler.org, 2013
;
;DEBUG = 1
.ifdef __ATARIXL__
.export sramprep
.import __SRPREP_LOAD__, __SRPREPCHNK_LAST__
.import __SHADOW_RAM_LOAD__, __SHADOW_RAM_SIZE__, __SHADOW_RAM_RUN__
.import __SHADOW_RAM2_LOAD__, __SHADOW_RAM2_SIZE__, __SHADOW_RAM2_RUN__
.import __CHARGEN_START__, __CHARGEN_SIZE__
.import __STARTADDRESS__ ; needed by xlmemchk.inc
.include "zeropage.inc"
.include "atari.inc"
.include "save_area.inc"
.macro print_string text
.local start, cont
jmp cont
start: .byte text, ATEOL
cont: ldx #0 ; channel 0
lda #<start
sta ICBAL,x ; address
lda #>start
sta ICBAH,x
lda #<(cont - start)
sta ICBLL,x ; length
lda #>(cont - start)
sta ICBLH,x
lda #PUTCHR
sta ICCOM,x
jsr CIOV_org
.endmacro
; ------------------------------------------------------------------------
; EXE load chunk header
.segment "SRPREPHDR"
.word __SRPREP_LOAD__
.word __SRPREPCHNK_LAST__ - 1
; ------------------------------------------------------------------------
; Actual code
.segment "SRPREP"
; ***** entry point *****
sramprep:
.ifdef DEBUG
print_string "entering stage #2"
.endif
; save values of modified system variables and ports
lda RAMTOP
sta RAMTOP_save
lda MEMTOP
sta MEMTOP_save
lda MEMTOP+1
sta MEMTOP_save+1
lda APPMHI
sta APPMHI_save
lda APPMHI+1
sta APPMHI_save+1
lda PORTB
sta PORTB_save
; disable BASIC
lda PORTB
ora #2
sta PORTB
.include "xlmemchk.inc" ; calculate lowest address used and new value for RAMTOP
ldx lowadr
stx MEMTOP
lda lowadr+1
sta MEMTOP+1
lda lodadr+1
sta RAMTOP
; set APPMHI to MEMLO (+ 1 for sanity)
lda MEMLO
clc
adc #1
sta APPMHI
lda MEMLO+1
adc #0
sta APPMHI+1
; issue a GRAPHICS 0 call (copied'n'pasted from TGI drivers) to move screen memory down
jsr findfreeiocb
.ifdef DEBUG ; only check in debug version, this shouldn't really happen(tm)
beq iocbok
print_string "Internal error, no free IOCB!"
jsr delay
jsr delay
jsr delay
jsr restore ; restore stuff we've changed
jmp (DOSVEC) ; abort loading
iocbok:
.endif
; reopen it in Graphics 0
lda #OPEN
sta ICCOM,x
lda #OPNIN | OPNOT
sta ICAX1,x
lda #0
sta ICAX2,x
lda #<screen_device
sta ICBAL,x
lda #>screen_device
sta ICBAH,x
lda #<screen_device_length
sta ICBLL,x
lda #>screen_device_length
sta ICBLH,x
jsr CIOV_org
bpl scrok
; shouldn't happen(tm)
print_string "Internal error, aborting..."
jsr delay
jsr delay
jsr delay
jsr restore ; restore stuff we've changed
jmp (DOSVEC) ; abort loading
scrok: ; now close it again -- we don't need it anymore
lda #CLOSE
sta ICCOM,x
jsr CIOV_org
; copy chargen to low memory, just after the next possible address beyond our loaded chunk data
.ifdef DEBUG
print_string "copy chargen to low memory"
.endif
lda #>__SRPREPCHNK_LAST__
sta ptr3+1
lda #<__SRPREPCHNK_LAST__
sta ptr3
beq cg_addr_ok
; page align the new chargen address
inc ptr3+1
lda #0
sta ptr3
cg_addr_ok:
lda ptr3+1
and #3
beq cg_addr_ok2
; align to next 1K boundary
lda ptr3+1
and #$fc
clc
adc #4
sta ptr3+1
cg_addr_ok2:
lda #<DCSORG
sta ptr1
lda #>DCSORG
sta ptr1+1
lda ptr3
sta ptr2
lda ptr3+1
pha ; needed later to set CHBAS/CHBASE
sta ptr2+1
lda #>__CHARGEN_SIZE__
sta tmp2
lda #<__CHARGEN_SIZE__
sta tmp1
jsr memcopy
.ifdef DEBUG
print_string "now setting up high memory"
.endif
; disable ROM
sei
ldx #0
stx NMIEN ; disable NMI
lda PORTB
and #$fe
tax
pla ; get temp. chargen address
sta WSYNC ; wait for horiz. retrace
stx PORTB ; now ROM is mapped out
; switch to temporary chargen
sta CHBASE
sta CHBAS
; copy shadow RAM contents to their destination (segment SHADOW_RAM)
lda #<__SHADOW_RAM_SIZE__
bne do_copy
lda #>__SHADOW_RAM_SIZE__
beq no_copy ; we have no shadow RAM contents
; ptr1 - src; ptr2 - dest; tmp1, tmp2 - len
do_copy:lda #<__SHADOW_RAM_LOAD__
sta ptr1
lda #>__SHADOW_RAM_LOAD__
sta ptr1+1
lda #<__SHADOW_RAM_RUN__
sta ptr2
lda #>__SHADOW_RAM_RUN__
sta ptr2+1
lda #<__SHADOW_RAM_SIZE__
sta tmp1
lda #>__SHADOW_RAM_SIZE__
sta tmp2
jsr memcopy
no_copy:
; copy shadow RAM #2 contents to their destination (segment SHADOW_RAM2)
lda #<__SHADOW_RAM2_SIZE__
bne do_copy2
lda #>__SHADOW_RAM2_SIZE__
beq no_copy2 ; we have no shadow RAM #2 contents
; ptr1 - src; ptr2 - dest; tmp1, tmp2 - len
do_copy2:
lda #<__SHADOW_RAM2_LOAD__
sta ptr1
lda #>__SHADOW_RAM2_LOAD__
sta ptr1+1
lda #<__SHADOW_RAM2_RUN__
sta ptr2
lda #>__SHADOW_RAM2_RUN__
sta ptr2+1
lda #<__SHADOW_RAM2_SIZE__
sta tmp1
lda #>__SHADOW_RAM2_SIZE__
sta tmp2
jsr memcopy
no_copy2:
; copy chargen to its new (final) location
lda ptr3
sta ptr1
lda ptr3+1
sta ptr1+1
lda #<__CHARGEN_START__
sta ptr2
lda #>__CHARGEN_START__
sta ptr2+1
lda #>__CHARGEN_SIZE__
sta tmp2
lda #<__CHARGEN_SIZE__
sta tmp1
jsr memcopy
; re-enable ROM
lda PORTB
ora #1
ldx #>DCSORG
sta WSYNC ; wait for horiz. retrace
sta PORTB
stx CHBASE
stx CHBAS
lda #$40
sta NMIEN ; enable VB again
cli ; and enable IRQs
.ifdef DEBUG
print_string "Stage #2 OK"
print_string "loading main chunk"
jsr delay
.endif
rts
.include "findfreeiocb.inc"
; routine taken from http://www.obelisk.demon.co.uk/6502/algorithms.html
;
; copy memory
; ptr1 - source
; ptr2 - destination
; tmp2:tmp1 - len
.proc memcopy
ldy #0
ldx tmp2
beq last
pagecp: lda (ptr1),y
sta (ptr2),y
iny
bne pagecp
inc ptr1+1
inc ptr2+1
dex
bne pagecp
last: cpy tmp1
beq done
lda (ptr1),y
sta (ptr2),y
iny
bne last
done: rts
.endproc
; clean up after a fatal error
restore:lda RAMTOP_save
sta RAMTOP
lda MEMTOP_save
sta MEMTOP
lda MEMTOP_save+1
sta MEMTOP+1
lda APPMHI_save
sta APPMHI
lda APPMHI_save+1
sta APPMHI+1
rts
; short delay
.proc delay
lda #10
@loop: jsr delay1
clc
sbc #0
bne @loop
rts
delay1: ldx #0
ldy #0
@loop: dey
bne @loop
dex
bne @loop
rts
.endproc
.ifdef DEBUG
.byte "HERE ****************** HERE ***************>>>>>>"
sramsize:
.word __SHADOW_RAM_SIZE__
.endif ; .ifdef DEBUG
screen_device: .byte "S:",0
screen_device_length = * - screen_device
.ifdef DEBUG
.byte " ** srprep ** end-->"
.endif
; ------------------------------------------------------------------------
; Provide empty SHADOW_RAM and SHADOW_RAM2 segments in order that the
; linker is happy if the user program doesn't have these segments.
.segment "SHADOW_RAM"
.segment "SHADOW_RAM2"
; ------------------------------------------------------------------------
; EXE load chunk "trailer" - sets INITAD
.segment "SRPREPTRL"
.word INITAD
.word INITAD+1
.word sramprep
.endif ; .ifdef __ATARIXL__

View File

@@ -8,7 +8,6 @@
; ;
.include "atari.inc" .include "atari.inc"
.include "errno.inc"
.export __sysrmdir .export __sysrmdir
.import __sysremove .import __sysremove
.import __dos_type .import __dos_type
@@ -17,7 +16,6 @@
.ifdef UCASE_FILENAME .ifdef UCASE_FILENAME
.import ucase_fn .import ucase_fn
.import addysp .import addysp
.importzp sreg
.importzp tmp3 .importzp tmp3
.ifdef DEFAULT_DEVICE .ifdef DEFAULT_DEVICE
.importzp tmp2 .importzp tmp2

215
libsrc/atari/system_check.s Normal file
View File

@@ -0,0 +1,215 @@
;
; Atari startup system check
;
; This routine gets loaded prior to the main part of the executable
; and checks if the system is compatible to run the program.
; For the XL target it checks whether the system is an XL type one
; and that enough memory is installed (which isn't the case for a 600XL).
; For the non-XL target it checks whether there is enough memory
; installed to run the program.
; For both targets it checks that the program won't load below MEMLO.
; If one of the checks fails, the loading of the main program
; is aborted by jumping to DOSVEC.
;
; Christian Groessler, chris@groessler.org, 2013
;
;DEBUG = 1
.export __SYSTEM_CHECK__: absolute = 1
.import __SYSCHK_LOAD__
.import __STARTADDRESS__
; the following imports are only needed for the 'atari' target version
.import __BSS_SIZE__, __BSS_RUN__
.import __STACKSIZE__
.import __RESERVED_MEMORY__
.include "zeropage.inc"
.include "atari.inc"
.macro print_string text
.local start, cont
jmp cont
start: .byte text, ATEOL
cont: ldx #0 ; channel 0
lda #<start
sta ICBAL,x ; address
lda #>start
sta ICBAH,x
lda #<(cont - start)
sta ICBLL,x ; length
lda #>(cont - start)
sta ICBLH,x
lda #PUTCHR
sta ICCOM,x
jsr CIOV_org
.endmacro
.macro print_string2 addr, len
ldx #0 ; channel 0
lda #<addr
sta ICBAL,x ; address
lda #>addr
sta ICBAH,x
lda #<len
sta ICBLL,x ; length
lda #>len
sta ICBLH,x
lda #PUTCHR
sta ICCOM,x
jsr CIOV_org
.endmacro
; ------------------------------------------------------------------------
; code
.segment "SYSCHK"
.ifdef __ATARIXL__
lmemerrxl_txt:
.byte "Not enough memory to move screen", ATEOL
.byte "memory to low memory. Consider using", ATEOL
.byte "a higher load address.", ATEOL
lmemerrxl_txt_len = * - lmemerrxl_txt
; no XL machine
no_xl: print_string "This program needs an XL machine."
jmp fail
; ***** entry point (atarixl) *****
syschk: lda $fcd8 ; from ostype.s
cmp #$a2
beq no_xl
; we have an XL machine, now check memory
lda RAMSIZ
cmp #$80
bcs sys_ok
jmp mem_err
sys_ok:
.include "xlmemchk.inc" ; calculate lowest address we will use when we move the screen buffer down
lda MEMLO
cmp lowadr
lda MEMLO+1
sbc lowadr+1
bcc memlo_ok
; load address was too low
print_string2 lmemerrxl_txt, lmemerrxl_txt_len
jsr delay ; long text takes longer to read, give user additional time
jmp fail
.else ; above 'atarixl', below 'atari'
.define CIOV_org CIOV ; the print_string macros use CIOV_org, map this to CIOV
lmemerr_txt:
.byte "Program would load below MEMLO.", ATEOL
.byte "Consider using a higher load address.", ATEOL
lmemerr_txt_len = * - lmemerr_txt
; ***** entry point (atari) *****
syschk:
sec
lda MEMTOP
sbc #<__RESERVED_MEMORY__
sta tmp
lda MEMTOP+1
sbc #>__RESERVED_MEMORY__
sta tmp+1
lda tmp
sec
sbc #<__STACKSIZE__
sta tmp
lda tmp+1
sbc #>__STACKSIZE__
sta tmp+1
;tmp contains address which must be above .bss's end
lda tmp
cmp #<(__BSS_RUN__ + __BSS_SIZE__)
lda tmp+1
sbc #>(__BSS_RUN__ + __BSS_SIZE__)
bcc mem_err ; program doesn't fit into memory
lda MEMLO
cmp #<__STARTADDRESS__
lda MEMLO+1
sbc #>__STARTADDRESS__
bcc memlo_ok
; load address was too low
print_string2 lmemerr_txt, lmemerr_txt_len
jsr delay ; long text takes longer to read, give user additional time
jmp fail
.endif
; all is well(tm), launch the application
memlo_ok:
.ifdef DEBUG
print_string "Stage #1 OK"
jsr delay
.endif
rts
; not enough memory
mem_err:print_string "Not enough memory."
fail: jsr delay
jmp (DOSVEC)
; short delay
.proc delay
lda #10
@loop: jsr delay1
clc
sbc #0
bne @loop
rts
delay1: ldx #0
ldy #0
@loop: dey
bne @loop
dex
bne @loop
rts
.endproc
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

@@ -4,6 +4,12 @@
.macpack longbranch .macpack longbranch
.ifdef __ATARIXL__
CIO_vec := my_CIOV
.else
CIO_vec := CIOV
.endif
; ****************************************************************************** ; ******************************************************************************
; ---------------------------------------------------------------------- ; ----------------------------------------------------------------------
@@ -18,7 +24,7 @@
.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
.addr $0000 ; Library reference libref: .addr $0000 ; Library reference
.word x_res ; X resolution .word x_res ; X resolution
.word y_res ; Y resolution .word y_res ; Y resolution
.byte colors ; Number of drawing colors .byte colors ; Number of drawing colors
@@ -111,6 +117,10 @@
text_dir: text_dir:
.byte 0 ; Text direction, .byte 0 ; Text direction,
.ifdef __ATARIXL__
my_CIOV:
.byte $4C, 0, 0
.endif
.code .code
; ****************************************************************************** ; ******************************************************************************
@@ -161,6 +171,17 @@ screen_device_length := * - screen_device
stx mask stx mask
.ifdef __ATARIXL__
; setup pointer to CIO
lda libref
sta my_CIOV+1
lda libref+1
sta my_CIOV+2
.endif
; Find a free IOCB ; Find a free IOCB
lda #$70 lda #$70
search: tax search: tax
@@ -202,7 +223,7 @@ switch: lda #OPEN
sta ICBLL,x sta ICBLL,x
lda #>screen_device_length lda #>screen_device_length
sta ICBLH,x sta ICBLH,x
jsr CIOV jsr CIO_vec
.if ::pages = 2 .if ::pages = 2
; Reserve 8K of high memory ; Reserve 8K of high memory
@@ -212,7 +233,7 @@ switch: lda #OPEN
; Close and reopen graphics ; Close and reopen graphics
lda #CLOSE lda #CLOSE
sta ICCOM,x sta ICCOM,x
jsr CIOV jsr CIO_vec
; Reopen graphics ; Reopen graphics
lda #OPEN lda #OPEN
sta ICCOM,x sta ICCOM,x
@@ -228,7 +249,7 @@ switch: lda #OPEN
sta ICBLL,x sta ICBLL,x
lda #>screen_device_length lda #>screen_device_length
sta ICBLH,x sta ICBLH,x
jsr CIOV jsr CIO_vec
; Save screen pointers ; Save screen pointers
lda SAVMSC + 1 lda SAVMSC + 1
sta p0scr sta p0scr
@@ -271,7 +292,7 @@ exit: sta error
; Close the S: device ; Close the S: device
lda #CLOSE lda #CLOSE
sta ICCOM,x sta ICCOM,x
jsr CIOV jsr CIO_vec
; Reopen it in Graphics 0 ; Reopen it in Graphics 0
lda #OPEN lda #OPEN
@@ -288,12 +309,12 @@ exit: sta error
sta ICBLL,x sta ICBLL,x
lda #>screen_device_length lda #>screen_device_length
sta ICBLH,x sta ICBLH,x
jsr CIOV jsr CIO_vec
; Now close it again; we don't need it anymore :) ; Now close it again; we don't need it anymore :)
lda #CLOSE lda #CLOSE
sta ICCOM,x sta ICCOM,x
jmp CIOV jmp CIO_vec
.endproc .endproc
; ****************************************************************************** ; ******************************************************************************
@@ -640,7 +661,7 @@ done10:
.endif .endif
sta ATACHR sta ATACHR
jmp CIOV jmp CIO_vec
.else ; USE_CIO_LINE .else ; USE_CIO_LINE

119
libsrc/atari/xlmemchk.inc Normal file
View File

@@ -0,0 +1,119 @@
;
; Christian Groessler, Jun-2013
;
; This routine is used in preparation to move the screen memory
; in front of the program.
;
; It calculates the value to put into RAMTOP for a subsequent
; "GRAPHICS 0" call, and the lowest address which will be used
; by the screen memory afterwards.
;
; inputs:
; __STARTADDRESS__ - load address of the program
; outputs:
; lodadr - (high byte only) value to
; write into RAMTOP
; lowadr - lowest address occupied by
; screen data
;
; When setting a display mode, the ROM takes the RAMTOP value
; and subtracts the size of the screen memory from it. This will
; become the new screen memory address.
; From this address it subtracts the size of the display list.
; This will become the new display list address.
; Screen memory cannot cross 4K boundaries and a display list
; cannot cross a 1K boundary.
;
; Work out a sane value for RAMTOP to prevent boundary crossing.
; RAMTOP is only one byte, it counts in memory pages.
;
; The ROM doesn't do this boundary checking, since it doesn't
; expect RAMTOP to have (rather) arbitrary values. For a
; "GRAPHICS 0" call and RAMTOP representing the possible physically
; available memory, boundary crossing cannot happen.
SCRBUFSZ = (40 * 24) ; size of mode 0 screen buffer
DLSZ = 32 ; size of mode 0 display list
scrmemtst:
; subtract screen memory size from our load address
lda lodadr
sec
sbc #<SCRBUFSZ
sta tstadr
lda lodadr+1
sbc #>SCRBUFSZ
sta tstadr+1
; check if a 4K boundary is crossed
lda lodadr+1
and #$f0
sta tmp
lda tstadr+1
and #$f0
cmp tmp
beq scrmemok
; if lodadr is at an exact 4K boundary, it's still ok
lda lodadr+1
and #$0f
beq scrmemok
; 4K boundary will be crossed, use this 4K boundary address as lodadr
al4k: lda lodadr+1
and #$f0
sta lodadr+1
bne scrmemtst
; not reached
.ifdef DEBUG
.byte "XLMEMCHK:>"
.endif
lodadr: .word __STARTADDRESS__ & $FF00 ; our program's load address, rounded down to page boundary
tstadr: .res 2
lowadr: .res 2
tmp: .res 1
; subtract display list size from calculated screen address
scrmemok:
lda tstadr
sec
sbc #<DLSZ
sta lowadr
lda tstadr+1
sbc #>DLSZ
sta lowadr+1
.if 0 ; this cannot happen
; check if a 1K boundary is crossed
lda tstadr+1
and #$fc
sta tmp
lda lowadr+1
and #$fc
cmp tmp
bne al4k ; 1K boundary will be crossed, decrease lodadr
.endif
; address of display list is ok
; decrease lowadr by two
lda lowadr
sec
sbc #2
sta lowadr
bcs dec_cont
dec lowadr+1
dec_cont:

15
libsrc/atmos/atmos.s Normal file
View File

@@ -0,0 +1,15 @@
;
; Expose include-file symbol names to C code.
;
.export _atmos_ping, _atmos_shoot, _atmos_explode
.export _atmos_zap, _atmos_tick, _atmos_tock
.include "atmos.inc"
_atmos_ping := PING
_atmos_shoot := SHOOT
_atmos_explode := EXPLODE
_atmos_zap := ZAP
_atmos_tick := TICK
_atmos_tock := TOCK

View File

@@ -5,7 +5,6 @@
.export em_libref .export em_libref
.export joy_libref .export joy_libref
; .export mouse_libref
.export ser_libref .export ser_libref
.export tgi_libref .export tgi_libref
@@ -13,6 +12,5 @@
em_libref := _exit em_libref := _exit
joy_libref := _exit joy_libref := _exit
;mouse_libref := _exit
ser_libref := _exit ser_libref := _exit
tgi_libref := _exit tgi_libref := _exit

View File

@@ -5,7 +5,6 @@
.export em_libref .export em_libref
.export joy_libref .export joy_libref
; .export mouse_libref
.export ser_libref .export ser_libref
.export tgi_libref .export tgi_libref
@@ -13,6 +12,5 @@
em_libref := _exit em_libref := _exit
joy_libref := _exit joy_libref := _exit
;mouse_libref := _exit
ser_libref := _exit ser_libref := _exit
tgi_libref := _exit tgi_libref := _exit

118
libsrc/cbm/exec.c Normal file
View File

@@ -0,0 +1,118 @@
/*
** Program-chaining function for Commodore platforms.
**
** 2013-09-04, Greg King
**
** This function exploits the program-chaining feature in CBM BASIC's ROM.
**
** CC65's CBM programs have a BASIC program stub. We start those programs by
** RUNning that stub; it SYSes to the Machine Language code. Normally, after
** the ML code exits, the BASIC ROM continues running the stub. But, it has
** no more statements; so, the program stops.
**
** This function puts the desired program's name and device number into a LOAD
** statement. Then, it points BASIC to that statement, so that the ROM will run
** that statement after this program quits. The ROM will load the next program,
** and will execute it (because the LOAD will be seen in a running program).
*/
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <device.h>
#if defined(__CBM610__)
# include <cbm610.h>
#elif defined(__CBM510__)
# include <cbm510.h>
#endif
/* The struct below is a line of BASIC code. It sits in the LOWCODE segment
** to make sure that it won't be hidden by a ROM when BASIC is re-enabled.
** The line is:
** 0 LOAD""+"" ,01
** After this function has written into the line, it might look like this:
** 0 LOAD""+"program name" ,08
**
** When BASIC's LOAD command asks the Kernal to load a file, it gives the
** Kernal a pointer to a file-name string. CC65's CBM programs use that
** pointer to give a copy of the program's name to main()'s argv[0] parameter.
** But, when BASIC uses a string literal that's in a program, it points
** directly to that literal -- in the models that don't use banked RAM
** (Pet/CBM, VIC-20, and 64). The literal is overwritten by the next program
** that's loaded. So, argv[0] would point to machine code. String operations
** create a new result string -- even when that operation changes nothing. The
** result is put in the string space at the top of BASIC's memory. So, the ""+
** in this BASIC line guarantees that argv[0] will get a name from a safe place.
*/
#pragma data-name(push, "LOWCODE")
static struct line {
const char end_of_line;
const struct line *const next;
const unsigned line_num;
const char load_token, quotes[2], add_token, quote;
char name[21];
const char comma;
char unit[3];
} basic = {
'\0', &basic + 1, /* high byte of link must be non-zero */
0, 0x93, "\"\"", 0xaa, '\"',
"\" ", /* format: "123:1234567890123456\"" */
',', "01"
};
#pragma data-name(pop)
/* These values are platform-specific. */
extern const struct line *txtptr;
#pragma zpsym("txtptr")
extern char basbuf[]; /* BASIC's input buffer */
extern void basbuf_len[];
#pragma zpsym("basbuf_len")
int __fastcall__ exec (const char* progname, const char* cmdline)
{
static int fd;
static unsigned char dv, n = 0;
/* Exclude devices that can't load files. */
dv = getcurrentdevice ();
if (dv < 8 && dv != 1 || dv > 30) {
return _mappederrno (9); /* illegal device number */
}
utoa (dv, basic.unit, 10);
/* Don't try to run a program that can't be found. */
fd = open (progname, O_RDONLY);
if (fd < 0) {
return fd;
}
close (fd);
do {
if ((basic.name[n] = progname[n]) == '\0') {
break;
}
} while (++n < 20); /* truncate long names */
basic.name[n] = '\"';
/* Build the next program's argument list. */
basbuf[0] = 0x8f; /* REM token */
basbuf[1] = '\0';
if (cmdline != NULL) {
strncat (basbuf, cmdline, (size_t)basbuf_len - 2);
}
#if defined(__CBM510__) || defined(__CBM610__)
pokewsys ((unsigned)&txtptr, (unsigned)&basic);
#else
txtptr = &basic;
#endif
/* (The return code, in ST, will be destroyed by LOAD.
** So, don't bother to set it here.)
*/
exit (__AX__);
}

28
libsrc/cbm/execvars.s Normal file
View File

@@ -0,0 +1,28 @@
;
; Platform-specific variables for the exec program-chaining function
;
.if .defined (__C128__)
.include "c128.inc"
.elseif .defined (__C16__)
.include "c16.inc"
.elseif .defined (__C64__)
.include "c64.inc"
.elseif .defined (__CBM510__)
.include "cbm510.inc"
.elseif .defined (__CBM610__)
.include "cbm610.inc"
.elseif .defined (__PET__)
.include "pet.inc"
.elseif .defined (__PLUS4__)
.include "plus4.inc"
.else
.include "vic20.inc"
.endif
.export _txtptr:zp, _basbuf, _basbuf_len:zp
_txtptr := TXTPTR
_basbuf := BASIC_BUF
_basbuf_len = BASIC_BUF_LEN

View File

@@ -56,9 +56,9 @@
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; A table that contains values that must be transfered from the system zero ; A table that contains values that must be transfered from the system zero
; page into out zero page. Contains pairs of bytes, first one is the address ; page into our zero page. Contains pairs of bytes; first one is the address
; in the system ZP, second one is our ZP address. The table goes into page 2, ; in the system ZP, second one is our ZP address. The table goes into page 2,
; but is declared here, because it is needed earlier. ; but is declared here because it is needed earlier.
.SEGMENT "PAGE2" .SEGMENT "PAGE2"
@@ -67,6 +67,8 @@
.byte $9F, DEVNUM .byte $9F, DEVNUM
.byte $CA, CURS_Y .byte $CA, CURS_Y
.byte $CB, CURS_X .byte $CB, CURS_X
.byte $E6, CURS_FLAG
.byte $E7, CURS_BLINK
.byte $EC, CHARCOLOR .byte $EC, CHARCOLOR
.endproc .endproc

131
libsrc/cbm510/mcbdefault.s Normal file
View File

@@ -0,0 +1,131 @@
;
; Default mouse callbacks for the CBM510 (P128)
;
; 2004-03-20, Ullrich von Bassewitz2
; 2013-06-25, Greg King
;
; All functions in this module should be interrupt-safe because they might
; be called from an interrupt handler.
;
.export _mouse_def_callbacks
.import vic:zp
.include "mouse-kernel.inc"
.include "cbm510.inc"
.macpack generic
; Sprite definitions. The first value can be changed to adjust the number
; of the sprite used for the mouse. All others depend on that value.
MOUSE_SPR = 0 ; Sprite used for the mouse
MOUSE_SPR_MASK = $01 .shl MOUSE_SPR ; Positive mask
MOUSE_SPR_NMASK = .lobyte(.not MOUSE_SPR_MASK) ; Negative mask
VIC_SPR_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register
VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register
; --------------------------------------------------------------------------
; Hide the mouse pointer. Always called with interrupts disabled.
.proc hide
ldy #15
sty IndReg
ldy #VIC_SPR_ENA
lda (vic),y
and #MOUSE_SPR_NMASK
sta (vic),y
ldy ExecReg
sty IndReg
rts
.endproc
; --------------------------------------------------------------------------
; Show the mouse pointer. Always called with interrupts disabled.
.proc show
ldy #15
sty IndReg
ldy #VIC_SPR_ENA
lda (vic),y
ora #MOUSE_SPR_MASK
sta (vic),y
ldy ExecReg
sty IndReg
rts
.endproc
; --------------------------------------------------------------------------
; Move the mouse pointer x position to the value in .XA. Always called with
; interrupts disabled.
.proc movex
ldy #15
sty IndReg
; Add the x correction; and, set the low byte. That frees .A.
add #<24 ; x correction
ldy #VIC_SPR_X
sta (vic),y
; Set the high byte
ldy #VIC_SPR_HI_X
txa
adc #>24
bnz @L1 ; Branch if high byte not zero
lda (vic),y ; Get high x bits of all sprites
and #MOUSE_SPR_NMASK ; Clear high bit for sprite
sta (vic),y
@L0: ldy ExecReg
sty IndReg
rts
@L1: lda (vic),y ; Get high x bits of all sprites
ora #MOUSE_SPR_MASK ; Set high bit for sprite
sta (vic),y
bnz @L0 ; branch always
.endproc
; --------------------------------------------------------------------------
; Move the mouse pointer y position to the value in .XA. Always called with
; interrupts disabled.
.proc movey
ldy #15
sty IndReg
add #50 ; y correction (first visible line)
ldy #VIC_SPR_Y
sta (vic),y ; Set y position
ldy ExecReg
sty IndReg
rts
.endproc
; --------------------------------------------------------------------------
; Callback structure
.rodata
_mouse_def_callbacks:
.addr hide
.addr show
.addr movex
.addr movey

View File

@@ -0,0 +1,444 @@
;
; Driver for the Inkwell Systems 170-C and 184-C lightpens.
;
; This driver reads only the main button on the 184-C.
;
; 2013-09-05, Greg King
;
.include "zeropage.inc"
.include "../extzp.inc"
.include "mouse-kernel.inc"
.include "cbm510.inc"
.macpack generic
; ------------------------------------------------------------------------
; Header. Includes jump table.
.segment "JUMPTABLE"
HEADER:
; Driver signature
.byte $6d, $6f, $75 ; ASCII "mou"
.byte MOUSE_API_VERSION ; Mouse driver API version number
; Library reference
LIBREF: .addr $0000
; Jump table
.addr INSTALL
.addr UNINSTALL
.addr HIDE
.addr SHOW
.addr SETBOX
.addr GETBOX
.addr MOVE
.addr BUTTONS
.addr POS
.addr INFO
.addr IOCTL
.addr IRQ
; Mouse driver flags
.byte MOUSE_FLAG_EARLY_IRQ
; Callback table, set by the kernel before INSTALL is called.
CHIDE: jmp $0000 ; Hide the cursor
CSHOW: jmp $0000 ; Show the cursor
CMOVEX: jmp $0000 ; Move the cursor to X co-ord.
CMOVEY: jmp $0000 ; Move the cursor to Y co-ord.
;----------------------------------------------------------------------------
; Constants
SCREEN_WIDTH = XSIZE * 8
SCREEN_HEIGHT = YSIZE * 8
;----------------------------------------------------------------------------
; Global variables. The bounding box values are sorted so that they can be
; written with the least effort in the SETBOX and GETBOX routines; so, don't
; re-order them.
.rodata
; Default values for below variables
; (We use ".proc" because we want to define both a label and a scope.)
.proc DefVars
.word 0 ; XMin
.word 0 ; YMin
.word SCREEN_WIDTH - 1 ; XMax
.word SCREEN_HEIGHT - 1 ; YMax
.endproc
.bss
Vars:
XMin: .res 2 ; X1 value of bounding box
YMin: .res 2 ; Y1 value of bounding box
XMax: .res 2 ; X2 value of bounding box
YMax: .res 2 ; Y2 value of bounding box
XPos: .res 2 ; Current lightpen position, X
YPos: .res 2 ; Current lightpen position, Y
OldPenX: .res 1 ; Previous HW-counter values
OldPenY: .res 1
.data
; Default Inkwell calibration.
; The first number is the width of the left border;
; the second number is the actual calibration value.
XOffset: .byte (24 + 24) / 2 ; x-offset
; Jump to a function that puts a new calibration value into XOffset.
Calibrate: jmp $0000
.code
;----------------------------------------------------------------------------
; INSTALL routine. Is called after the driver is loaded into memory. If
; possible, check if the hardware is present.
; Must return a MOUSE_ERR_xx code in .XA.
INSTALL:
; Initiate variables. Just copy the default stuff over.
ldx #.sizeof (DefVars) - 1
@L0: lda DefVars,x
sta Vars,x
dex
bpl @L0
ldx #15 ; Change to system bank
stx IndReg
ldy #VIC_LPEN_X
lda (vic),y
sta OldPenX
ldy #VIC_LPEN_Y
lda (vic),y
sta OldPenY
ldx ExecReg ; Change back to execution bank
stx IndReg
; Call a calibration function through the library-reference.
lda LIBREF
ldx LIBREF+1
sta ptr1 ; Point to mouse_adjuster
stx ptr1+1
ldy #1
lda (ptr1),y
bze @L1 ; Don't call pointer if it's NULL
sta Calibrate+2 ; Point to function
dey
lda (ptr1),y
sta Calibrate+1
lda #<XOffset ; Function will set this variable
ldx #>XOffset
jsr Calibrate
; Be sure that the lightpen cursor is invisible and at the default location.
; It needs to be done here because the lightpen interrupt handler doesn't
; set the lightpen position if it hasn't changed.
@L1: sei
jsr CHIDE
lda #<(SCREEN_HEIGHT / 2)
ldx #>(SCREEN_HEIGHT / 2)
jsr MoveY
lda #<(SCREEN_WIDTH / 2)
ldx #>(SCREEN_WIDTH / 2)
jsr MoveX
cli
; Done, return zero.
lda #MOUSE_ERR_OK
tax
rts
;----------------------------------------------------------------------------
; UNINSTALL routine. Is called before the driver is removed from memory.
; No return code required (the driver is removed from memory on return).
UNINSTALL := HIDE ; Hide cursor on exit
;----------------------------------------------------------------------------
; HIDE routine. Is called to hide the lightpen pointer. The mouse kernel manages
; a counter for calls to show/hide, and the driver entry point is called only
; if the mouse is currently visible, and should get hidden. For most drivers,
; no special action is required besides hiding the lightpen cursor.
; No return code required.
HIDE: sei
jsr CHIDE
cli
rts
;----------------------------------------------------------------------------
; SHOW routine. Is called to show the lightpen pointer. The mouse kernel manages
; a counter for calls to show/hide, and the driver entry point is called only
; if the mouse is currently hidden, and should become visible. For most drivers,
; no special action is required besides enabling the lightpen cursor.
; No return code required.
SHOW: sei
jsr CSHOW
cli
rts
;----------------------------------------------------------------------------
; SETBOX: Set the lightpen bounding box. The parameters are passed as they come
; from the C program, that is, a pointer to a mouse_box struct in .XA.
; No checks are done if the lightpen is currently inside the box, that is the job
; of the caller. It is not necessary to validate the parameters; trust the
; caller; and, save some code here. No return code required.
SETBOX: sta ptr1
stx ptr1+1 ; Save data pointer
ldy #.sizeof (MOUSE_BOX) - 1
sei
@L1: lda (ptr1),y
sta XMin,y
dey
bpl @L1
cli
rts
;----------------------------------------------------------------------------
; GETBOX: Return the lightpen bounding box. The parameters are passed as they
; come from the C program, that is, a pointer to a mouse_box struct in .XA.
GETBOX: sta ptr1
stx ptr1+1 ; Save data pointer
ldy #.sizeof (MOUSE_BOX) - 1
@L1: lda XMin,y
sta (ptr1),y
dey
bpl @L1
rts
;----------------------------------------------------------------------------
; MOVE: Move the mouse to a new position. The position is passed as it comes
; from the C program, that is: X on the stack and Y in .XA. The C wrapper will
; remove the parameter from the stack on return.
; No checks are done if the new position is valid (within the bounding box or
; the screen). No return code required.
;
MOVE: sei ; No interrupts
jsr MoveY
ldy #$01
lda (sp),y
tax
dey
lda (sp),y
jsr MoveX ; Move the cursor
cli ; Allow interrupts
rts
;----------------------------------------------------------------------------
; BUTTONS: Return the button mask in .XA.
BUTTONS:
ldx #15 ; To system bank
stx IndReg
ldy #CIA::PRB
lda (cia2),y ; Read joystick inputs
ldx ExecReg ; Back to execution bank
stx IndReg
; Joystick 1, directions in bits 3-0.
; Make the lightpen button look like a 1351 mouse.
asl a ; Move joystick-left bit ...
asl a ; ... to fire-button bit
eor #MOUSE_BTN_LEFT
and #MOUSE_BTN_LEFT
ldx #>0
rts
;----------------------------------------------------------------------------
; POS: Return the lightpen position in the MOUSE_POS struct pointed to by ptr1.
; No return code required.
POS: ldy #MOUSE_POS::XCOORD ; Structure offset
sei ; Disable interrupts
lda XPos ; Transfer the position
sta (ptr1),y
lda XPos+1
iny
sta (ptr1),y
lda YPos
iny
sta (ptr1),y
lda YPos+1
cli ; Enable interrupts
iny
sta (ptr1),y ; Store last byte
rts
;----------------------------------------------------------------------------
; INFO: Returns lightpen position and current button mask in the MOUSE_INFO
; struct pointed to by ptr1. No return code required.
;
; We're cheating here, to keep the code smaller: The first fields of the
; mouse_info struct are identical to the mouse_pos struct; so, we'll just
; call _mouse_pos to initiate the struct pointer, and fill the position
; fields.
INFO: jsr POS
; Fill in the button state
jsr BUTTONS ; Will not touch ptr1
ldy #MOUSE_INFO::BUTTONS
sta (ptr1),y
rts
;----------------------------------------------------------------------------
; 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 .XA.
;
IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioctls, for now
ldx #>MOUSE_ERR_INV_IOCTL
rts
;----------------------------------------------------------------------------
; IRQ: Irq.-handler entry point. Called as a subroutine, but in the IRQ context
; (so, be careful). The routine MUST return carry set if the interrupt has been
; 'handled' -- which means that the interrupt source is gone. Otherwise, it
; MUST return carry clear.
;
IRQ: ldx #15 ; To system bank
stx IndReg
; Read the VIC-II lightpen registers.
ldy #VIC_LPEN_Y
lda (vic),y
cmp OldPenY
; Skip processing if nothing has changed.
beq @SkipY
sta OldPenY
ldx ExecReg ; Back to execution bank
stx IndReg
; Subtract the height of the top border, so that the lightpen co-ordinate
; will match the TGI co-ordinate.
sub #50
tay ; Remember low byte
ldx #>0
; Limit the Y co-ordinate to the bounding box.
txa
cpy YMin
sbc YMin+1
bpl @L3
ldy YMin
ldx YMin+1
jmp @L4
@L3: txa
cpy YMax
sbc YMax+1
bmi @L4
ldy YMax
ldx YMax+1
@L4: tya
jsr MoveY
ldx #15 ; To system bank
stx IndReg
@SkipY: ldy #VIC_LPEN_X
lda (vic),y
ldx ExecReg ; Back to execution bank
stx IndReg
cmp OldPenX
; Skip processing if nothing has changed.
beq @SkipX
sta OldPenX
; Adjust the value by the calibration offset.
sub XOffset
; Calculate the new X co-ordinate.
; The VIC-II register is eight bits; but, the screen co-ordinate is nine bits.
; Therefore, the VIC-II number is doubled. Then, it points to every other pixel;
; but, it can reach across the screen.
asl a
tay ; Remember low byte
lda #>0
rol a
tax ; Remember high byte
; Limit the X co-ordinate to the bounding box.
cpy XMin
sbc XMin+1
bpl @L1
ldy XMin
ldx XMin+1
jmp @L2
@L1: txa
cpy XMax
sbc XMax+1
bmi @L2
ldy XMax
ldx XMax+1
@L2: tya
jsr MoveX
; Done
@SkipX: clc ; Interrupt not "handled"
rts
; Move the lightpen pointer to the new Y pos.
MoveY: sta YPos
stx YPos+1
jmp CMOVEY
; Move the lightpen pointer to the new X pos.
MoveX: sta XPos
stx XPos+1
jmp CMOVEX

View File

@@ -0,0 +1,445 @@
;
; Driver for a "joystick mouse".
;
; 2009-09-26, Ullrich von Bassewitz
; 2013-09-05, Greg King
;
.include "zeropage.inc"
.include "../extzp.inc"
.include "mouse-kernel.inc"
.include "cbm510.inc"
.macpack generic
; ------------------------------------------------------------------------
; Header. Includes jump table
.segment "JUMPTABLE"
HEADER:
; Driver signature
.byte $6d, $6f, $75 ; ASCII "mou"
.byte MOUSE_API_VERSION ; Mouse driver API version number
; Library reference
.addr $0000
; Jump table
.addr INSTALL
.addr UNINSTALL
.addr HIDE
.addr SHOW
.addr SETBOX
.addr GETBOX
.addr MOVE
.addr BUTTONS
.addr POS
.addr INFO
.addr IOCTL
.addr IRQ
; Mouse driver flags
.byte MOUSE_FLAG_LATE_IRQ
; Callback table, set by the kernel before INSTALL is called.
CHIDE: jmp $0000 ; Hide the cursor
CSHOW: jmp $0000 ; Show the cursor
CMOVEX: jmp $0000 ; Move the cursor to x co-ord.
CMOVEY: jmp $0000 ; Move the cursor to y co-ord.
;----------------------------------------------------------------------------
; Constants
SCREEN_HEIGHT = YSIZE * 8
SCREEN_WIDTH = XSIZE * 8
.scope JOY
UP = %00000001
DOWN = %00000010
LEFT = %00000100
RIGHT = %00001000
FIRE = %00010000
.endscope
;----------------------------------------------------------------------------
; Global variables. The bounding box values are sorted so that they can be
; written with the least effort in the SETBOX and GETBOX routines; so, don't
; re-order them.
.bss
Vars:
YPos: .res 2 ; Current mouse position, y
XPos: .res 2 ; Current mouse position, x
XMin: .res 2 ; X1 value of bounding box
YMin: .res 2 ; Y1 value of bounding box
XMax: .res 2 ; X2 value of bounding box
YMax: .res 2 ; Y2 value of bounding box
; Temporary value used in the interrupt handler
Temp: .res 1
; Default values for above variables
.rodata
.proc DefVars
.word SCREEN_HEIGHT / 2 ; YPos
.word SCREEN_WIDTH / 2 ; XPos
.word 0 ; XMin
.word 0 ; YMin
.word SCREEN_WIDTH - 1 ; XMax
.word SCREEN_HEIGHT - 1 ; YMax
.endproc
.code
;----------------------------------------------------------------------------
; INSTALL routine. Is called after the driver is loaded into memory. If
; possible, check if the hardware is present.
; Must return a MOUSE_ERR_xx code in .XA.
INSTALL:
; Initiate variables; just copy the default stuff over.
ldx #.sizeof(DefVars) - 1
@L1: lda DefVars,x
sta Vars,x
dex
bpl @L1
; Be sure the mouse cursor is invisible and at the default location. We
; need to do that here because our mouse interrupt handler doesn't set the
; mouse position if it hasn't changed.
sei
jsr CHIDE
lda XPos
ldx XPos+1
jsr CMOVEX
lda YPos
ldx YPos+1
jsr CMOVEY
cli
; Done, return zero.
ldx #>MOUSE_ERR_OK
txa
rts
;----------------------------------------------------------------------------
; UNINSTALL routine. Is called before the driver is removed from memory.
; No return code required (the driver is removed from memory, on return).
UNINSTALL := HIDE ; Hide cursor, on exit
;----------------------------------------------------------------------------
; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
; a counter for calls to show/hide; and, the driver entry point is called only
; if the mouse currently is visible and should get hidden. For most drivers,
; no special action is required besides hiding the mouse cursor.
; No return code required.
HIDE: sei
jsr CHIDE
cli
rts
;----------------------------------------------------------------------------
; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
; a counter for calls to show/hide; and, the driver entry point is called only
; if the mouse currently is hidden and should become visible. For most drivers,
; no special action is required besides enabling the mouse cursor.
; No return code required.
SHOW: sei
jsr CSHOW
cli
rts
;----------------------------------------------------------------------------
; SETBOX: Set the mouse bounding box. The parameters are passed as they come
; from the C program, that is, a pointer to a mouse_box struct in .XA.
; No checks are done if the mouse currently is inside the box; that is the job
; of the caller. It is not necessary to validate the parameters; trust the
; caller, and save some code here. No return code required.
SETBOX: sta ptr1
stx ptr1+1 ; Save data pointer
ldy #.sizeof (MOUSE_BOX) - 1
sei
@L1: lda (ptr1),y
sta XMin,y
dey
bpl @L1
cli
rts
;----------------------------------------------------------------------------
; GETBOX: Return the mouse bounding box. The parameters are passed as they
; come from the C program, that is, a pointer to a mouse_box struct in .XA.
GETBOX: sta ptr1
stx ptr1+1 ; Save data pointer
ldy #.sizeof (MOUSE_BOX) - 1
@L1: lda XMin,y
sta (ptr1),y
dey
bpl @L1
rts
;----------------------------------------------------------------------------
; MOVE: Move the mouse to a new position. The position is passed as it comes
; from the C program, that is: x on the stack and y in .XA. The C wrapper will
; remove the parameter from the stack, on return.
; No checks are done if the new position is valid (within the bounding box or
; the screen). No return code required.
;
MOVE: sei ; No interrupts
jsr MoveY ; Set new y position
ldy #1
lda (sp),y
sta XPos+1
tax
dey
lda (sp),y
jsr MoveX ; Move the pointer
cli ; Allow interrupts
rts
;----------------------------------------------------------------------------
; BUTTONS: Return the button mask in .XA.
; Joystick 2's fire button is the left mouse button.
; Joystick 1's fire button is the right mouse button.
BUTTONS:
ldx #15 ; Switch to the system bank
stx IndReg
; Get the fire-button bits
ldy #CIA::PRA
lda (cia2),y
; Switch back to the execution bank.
ldy ExecReg
sty IndReg
; Joystick 2, fire button is in bit 7.
; Joystick 1, fire button is in bit 6.
and #%11000000
asl a ; Move bits 7,6 to bits 1,0
rol a
rol a
adc #%00001110 ; Move bit 1 to bit 4
and #MOUSE_BTN_LEFT | MOUSE_BTN_RIGHT
; Bits go up when buttons go down.
eor #MOUSE_BTN_LEFT | MOUSE_BTN_RIGHT
ldx #>0
rts
;----------------------------------------------------------------------------
; INFO: Returns mouse position and current button mask in the MOUSE_INFO
; struct pointed to by ptr1. No return code required.
;
; We're cheating here to keep the code smaller: The first fields of the
; mouse_info struct are identical to the mouse_pos struct; so, we just will
; use _mouse_pos to fill the position fields.
INFO: jsr BUTTONS
; Fill in the button state.
ldy #MOUSE_INFO::BUTTONS
sta (ptr1),y
; jmp POS ; Fall through
;----------------------------------------------------------------------------
; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
; No return code required.
POS: ldy #MOUSE_POS::XCOORD ; Structure offset
sei ; Disable interrupts
lda XPos ; Transfer the position
sta (ptr1),y
lda XPos+1
iny
sta (ptr1),y
lda YPos
iny
sta (ptr1),y
lda YPos+1
cli ; Enable interrupts
iny
sta (ptr1),y ; Store last byte
rts ; Done
;----------------------------------------------------------------------------
; 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 .XA.
;
IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioctls, for now
ldx #>MOUSE_ERR_INV_IOCTL
rts
;----------------------------------------------------------------------------
; IRQ: Irq.-handler entry point. Called as a subroutine, but in the IRQ context
; (so, be careful). The routine MUST return carry set if the interrupt has been
; 'handled' -- which means that the interrupt source is gone. Otherwise, it
; MUST return carry clear.
; Reads joystick 2.
;
IRQ: ldy #15 ; Switch to the system bank
sty IndReg
; Get the direction bits.
ldy #CIA::PRB
lda (cia2),y ; Read joystick inputs
; Switch back to the execution bank.
ldy ExecReg
sty IndReg
; Joystick 2, directions in bits 7-4.
; Mask the relevant bits.
and #$F0
eor #$F0 ; All bits are inverted
sta Temp
; Check left/right.
and #(JOY::LEFT | JOY::RIGHT) << 4
bze @SkipX
; We will cheat here, and rely on the fact that either the left OR the right
; bit can be active.
and #JOY::RIGHT << 4 ; Check RIGHT bit
bnz @Right
lda #<-1
tax
bnz @AddX ; Branch always
@Right: lda #<1
ldx #>1
; Calculate the new x co-ordinate (--> .YA).
@AddX: add XPos
tay ; Remember low byte
txa
adc XPos+1
tax
; Limit the x co-ordinate to the bounding box.
cpy XMin
sbc XMin+1
bpl @L1
ldy XMin
ldx XMin+1
jmp @L2
@L1: txa
cpy XMax
sbc XMax+1
bmi @L2
ldy XMax
ldx XMax+1
@L2: tya
jsr MoveX
; Calculate the y movement vector.
@SkipX: lda Temp ; Get joystick again
and #(JOY::UP | JOY::DOWN) << 4 ; Check up/down
bze @SkipY
; We will cheat here, and rely on the fact that either the up OR the down
; bit can be active.
and #JOY::UP << 4 ; Check UP bit
bze @Down
lda #<-1
tax
bnz @AddY
@Down: lda #<1
ldx #>1
; Calculate the new y co-ordinate (--> .YA).
@AddY: add YPos
tay ; Remember low byte
txa
adc YPos+1
tax
; Limit the y co-ordinate to the bounding box.
cpy YMin
sbc YMin+1
bpl @L3
ldy YMin
ldx YMin+1
jmp @L4
@L3: txa
cpy YMax
sbc YMax+1
bmi @L4
ldy YMax
ldx YMax+1
@L4: tya
jsr MoveY
; Done
@SkipY: clc ; Interrupt not handled
rts
; Move the mouse pointer to the new x pos.
MoveX: sta XPos
stx XPos+1
jmp CMOVEX
; Move the mouse pointer to the new y pos.
MoveY: sta YPos
stx YPos+1
jmp CMOVEY

View File

@@ -0,0 +1,13 @@
;
; Address of the static standard mouse driver
;
; 2012-11-01, Oliver Schmidt
; 2013-08-06, Greg King
;
; const void mouse_static_stddrv[];
;
.export _mouse_static_stddrv
.import _cbm510_joy_mou
_mouse_static_stddrv := _cbm510_joy_mou

View File

@@ -0,0 +1,16 @@
;
; Name of the standard mouse driver
;
; 2009-09-11, Ullrich von Bassewitz
; 2013-06-25, Greg King
;
; const char mouse_stddrv[];
;
.export _mouse_stddrv
.rodata
_mouse_stddrv: .asciiz "cbm510-joy.mou"

23
libsrc/cbm510/mouseref.s Normal file
View File

@@ -0,0 +1,23 @@
;
; Pointer for library references by device drivers.
;
; 2013-07-25, Greg King
;
.export mouse_libref, _pen_adjuster
.data
mouse_libref: ; generic label for mouse-kernel
; A program optionally can set this pointer to a function that gives
; a calibration value to a driver. If this pointer isn't NULL,
; then a driver that wants a value can call that function.
;
; The function might read a value from a file; or, it might ask the user
; to help calibrate the driver.
;
; void __fastcall__ (*pen_adjuster)(unsigned char *) = NULL;
;
_pen_adjuster:
.addr $0000

94
libsrc/cbm510/pencalib.c Executable file
View File

@@ -0,0 +1,94 @@
/*
** Calibrate lightpen drivers to the current video hardware.
**
** 2013-09-05, Greg King
**
*/
#include <conio.h>
#include <mouse.h>
#include <pen.h>
#define COMMAND1 "Adjust by clicking on line."
#define COMMAND2 "Finish by clicking off bar."
/*
** There is a delay between when the VIC sends its signal, and when the display
** shows that signal. There is another delay between the display and when
** the lightpen says that it saw that signal. Each display and pen is different.
** Therefore, the driver must be calibrated to them. A white bar is painted on
** the screen; and, a line is drawn down the middle of it. When the user clicks
** on that line, the difference between its position and where the VIC thinks
** that the pen is pointing becomes an offset that is subtracted from what the
** VIC sees.
*/
void __fastcall__ pen_calibrate (unsigned char *XOffset)
{
unsigned char oldBg = bgcolor (COLOR_BLUE);
unsigned char oldText = textcolor (COLOR_GRAY3);
unsigned char oldRev = revers (1);
unsigned char sprite0Color = peekbsys ((unsigned)&VIC.spr_color[0]);
unsigned char width, width2, height, height4, height8;
struct mouse_info info;
screensize (&width, &height);
width2 = width / 2;
height4 = height / 4;
height8 = height4 * 8;
/* Draw a bar and line. */
clrscr ();
cclearxy (0, height4, height4 * width);
cvlinexy (width2, height4 + 1, height4 - 2);
revers (0);
/* Print instructions. */
cputsxy (width2 - (sizeof COMMAND1) / 2, height / 2 + 1, COMMAND1);
cputsxy (width2 - (sizeof COMMAND2) / 2, height / 2 + 3, COMMAND2);
pokebsys ((unsigned)&VIC.spr_color[0], COLOR_GRAY2);
mouse_show ();
mouse_move (width2 * 8, height8 / 2);
for (;;) {
/* Wait for the main button to be released. */
do ; while ((mouse_buttons () & MOUSE_BTN_LEFT));
/* Wait for the main button to be pressed. */
do {
mouse_info (&info);
} while (!(info.buttons & MOUSE_BTN_LEFT));
/* Find out if the pen is on or off the bar. */
if (info.pos.y < height8 || info.pos.y >= height8 * 2) {
break;
}
/* On the bar; adjust the offset. */
/* Characters are eight pixels wide.
** The VIC-II sees every other pixel;
** so, we use half of the difference.
*/
*XOffset += (info.pos.x - (width2 * 8 + 8/2)) / 2;
}
/* Off the bar; wait for the main button to be released. */
do ; while ((mouse_buttons () & MOUSE_BTN_LEFT));
mouse_hide ();
pokebsys ((unsigned)&VIC.spr_color[0], sprite0Color);
revers (oldRev);
textcolor (oldText);
bgcolor (oldBg);
clrscr ();
}

View File

@@ -1,8 +1,9 @@
; ;
; Ullrich von Bassewitz, 02.06.1998 ; 1998-06-02, Ullrich von Bassewitz
; 2013-08-28, Greg King
; ;
; char* strlower (char* s); ; char* __fastcall__ strlower (char* s);
; char* strlwr (char* s); ; char* __fastcall__ strlwr (char* s);
; ;
; Non-ANSI ; Non-ANSI
; ;
@@ -19,7 +20,7 @@ _strlwr:
sta ptr1 ; Save s (working copy) sta ptr1 ; Save s (working copy)
stx ptr1+1 stx ptr1+1
sta ptr2 sta ptr2
sta ptr2+1 ; save function result stx ptr2+1 ; save function result
ldy #0 ldy #0
loop: lda (ptr1),y ; get character loop: lda (ptr1),y ; get character

View File

@@ -102,7 +102,7 @@ long __fastcall__ strtol (const char* nptr, char** endptr, int base)
*/ */
if (endptr) { if (endptr) {
if (CvtCount > 0) { if (CvtCount > 0) {
*endptr = (char*) S - 1; *endptr = (char*) S;
} else { } else {
*endptr = (char*) nptr; *endptr = (char*) nptr;
} }

View File

@@ -97,7 +97,7 @@ unsigned long __fastcall__ strtoul (const char* nptr, char** endptr, int base)
*/ */
if (endptr) { if (endptr) {
if (CvtCount > 0) { if (CvtCount > 0) {
*endptr = (char*) S - 1; *endptr = (char*) S;
} else { } else {
*endptr = (char*) nptr; *endptr = (char*) nptr;
} }

View File

@@ -1,8 +1,9 @@
; ;
; Ullrich von Bassewitz, 02.06.1998 ; 1998-06-02, Ullrich von Bassewitz
; 2013-08-28, Greg King
; ;
; char* strupper (char* s); ; char* __fastcall__ strupper (char* s);
; char* strupr (char* s); ; char* __fastcall__ strupr (char* s);
; ;
; Non-ANSI ; Non-ANSI
; ;
@@ -19,7 +20,7 @@ _strupr:
sta ptr1 ; Save s (working copy) sta ptr1 ; Save s (working copy)
stx ptr1+1 stx ptr1+1
sta ptr2 sta ptr2
sta ptr2+1 ; save function result stx ptr2+1 ; save function result
ldy #0 ldy #0
loop: lda (ptr1),y ; get character loop: lda (ptr1),y ; get character

View File

@@ -27,10 +27,10 @@
; Restore timep and check if it is NULL ; Restore timep and check if it is NULL
pla pla
sta ptr1 sta ptr1+1
pla pla
sta ptr1+1 ; Restore timep sta ptr1 ; Restore timep
ora ptr1 ; timep == 0? ora ptr1+1 ; timep == 0?
beq @L1 beq @L1
; timep is not NULL, store the result there ; timep is not NULL, store the result there

View File

@@ -13,7 +13,6 @@
MAXARGS = 10 ; Maximum number of arguments allowed MAXARGS = 10 ; Maximum number of arguments allowed
REM = $8f ; BASIC token-code REM = $8f ; BASIC token-code
NAME_LEN = 16 ; maximum length of command-name NAME_LEN = 16 ; maximum length of command-name
BASIC_BUF= $200
;--------------------------------------------------------------------------- ;---------------------------------------------------------------------------

View File

@@ -3,7 +3,7 @@
** Will work for the C64/C128/CBM510/Atari/Apple2. ** Will work for the C64/C128/CBM510/Atari/Apple2.
** **
** 2001-09-13, Ullrich von Bassewitz ** 2001-09-13, Ullrich von Bassewitz
** 2013-07-25, Greg King ** 2013-09-05, Greg King
** **
*/ */
@@ -85,7 +85,12 @@ static const unsigned char MouseSprite[64] = {
static void __fastcall__ CheckError (const char* S, unsigned char Error) static void __fastcall__ CheckError (const char* S, unsigned char Error)
{ {
if (Error != MOUSE_ERR_OK) { if (Error != MOUSE_ERR_OK) {
cprintf ("%s: %s(%u)\r\n", S, mouse_geterrormsg (Error), Error); cprintf ("\n%s: %s(%u)\r\n", S, mouse_geterrormsg (Error), Error);
/* Wait for a key-press, so that some platforms can show the error
** message before they remove the current screen.
*/
cgetc();
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
} }
@@ -154,7 +159,7 @@ int main (void)
cursor (0); cursor (0);
clrscr (); clrscr ();
/* The pointer is created before the driver is installed, /* The pointer should be created before the driver is installed,
** in case a lightpen driver needs it during calibration. ** in case a lightpen driver needs it during calibration.
*/ */
@@ -178,7 +183,7 @@ int main (void)
** the value will be put into this file, for the next time. ** the value will be put into this file, for the next time.
** (Other drivers will ignore this.) ** (Other drivers will ignore this.)
*/ */
#ifdef __CBM__ #if defined(__C64__) || defined(__C128__) || defined(__CBM510__)
pen_adjust ("pen.dat"); pen_adjust ("pen.dat");
#endif #endif
@@ -222,8 +227,13 @@ top:
/* Put a cross at the center of the screen. */ /* Put a cross at the center of the screen. */
gotoxy (width / 2 - 3, height / 2 - 1); gotoxy (width / 2 - 3, height / 2 - 1);
#if defined(__CBM__)
cprintf ("%3u,%3u\r\n%*s\xDB", width / 2 * 8 + 4, height / 2 * 8 + 4, cprintf ("%3u,%3u\r\n%*s\xDB", width / 2 * 8 + 4, height / 2 * 8 + 4,
width / 2, ""); width / 2, "");
#else
cprintf ("%3u,%3u\r\n%*s+", width / 2 * 8 + 4, height / 2 * 8 + 4,
width / 2, "");
#endif
/* Test loop */ /* Test loop */
ShowState (Jailed, Invisible); ShowState (Jailed, Invisible);

View File

@@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2012, Ullrich von Bassewitz */ /* (C) 1998-2013, Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@@ -38,6 +38,7 @@
#include <errno.h> #include <errno.h>
/* common */ /* common */
#include "cmdline.h"
#include "exprdefs.h" #include "exprdefs.h"
#include "libdefs.h" #include "libdefs.h"
#include "print.h" #include "print.h"
@@ -60,7 +61,7 @@
/*****************************************************************************/ /*****************************************************************************/
/* Name of the library file */ /* Name of the library file */
const char* LibName = 0; const char* LibName = 0;
@@ -101,7 +102,7 @@ static void ReadHeader (void)
} }
Header.Flags = Read16 (Lib); Header.Flags = Read16 (Lib);
Header.IndexOffs = Read32 (Lib); Header.IndexOffs = Read32 (Lib);
} }
@@ -229,7 +230,9 @@ void LibOpen (const char* Name, int MustExist, int NeedTemp)
if (MustExist) { if (MustExist) {
Error ("Library `%s' does not exist", Name); Error ("Library `%s' does not exist", Name);
} else { } else {
Warning ("Library `%s' not found - will be created", Name); /* Announce the library's creation if ar65 is verbose. */
Print (stdout, 1,
"%s: Library `%s' will be created.\n", ProgName, Name);
} }
} else { } else {
@@ -307,7 +310,7 @@ static void LibCheckExports (ObjData* O)
unsigned I; unsigned I;
/* Let the user know what we do */ /* Let the user know what we do */
Print (stdout, 1, "Module `%s' (%u exports):\n", O->Name, CollCount (&O->Exports)); Print (stdout, 2, "Module `%s' (%u exports):\n", O->Name, CollCount (&O->Exports));
/* Insert the exports into the global table */ /* Insert the exports into the global table */
for (I = 0; I < CollCount (&O->Exports); ++I) { for (I = 0; I < CollCount (&O->Exports); ++I) {
@@ -316,7 +319,7 @@ static void LibCheckExports (ObjData* O)
const char* Name = CollConstAt (&O->Exports, I); const char* Name = CollConstAt (&O->Exports, I);
/* Insert the name into the hash table */ /* Insert the name into the hash table */
Print (stdout, 1, " %s\n", Name); Print (stdout, 2, " %s\n", Name);
ExpInsert (Name, O); ExpInsert (Name, O);
} }
} }

View File

@@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2012, Ullrich von Bassewitz */ /* (C) 1998-2013, Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@@ -60,11 +60,12 @@
static void Usage (void) static void Usage (void)
/* Print usage information and exit */ /* Print usage information and exit */
{ {
printf ("Usage: %s <operation> lib file|module ...\n" fprintf (stderr, "Usage: %s <operation ...> lib file|module ...\n"
"Operation is one of:\n" "Operations are some of:\n"
"\ta\tAdd modules\n" "\ta\tAdd modules\n"
"\td\tDelete modules\n" "\td\tDelete modules\n"
"\tl\tList library contents\n" "\tl\tList library contents\n"
"\tv\tIncrease verbosity (put before other operation)\n"
"\tx\tExtract modules\n" "\tx\tExtract modules\n"
"\tV\tPrint the archiver version\n", "\tV\tPrint the archiver version\n",
ProgName); ProgName);

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2001-2009 Ullrich von Bassewitz */ /* (C) 2001-2013, Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -58,7 +58,8 @@ typedef enum {
LI_DIRECT = 0x01, /* Direct op may be used */ LI_DIRECT = 0x01, /* Direct op may be used */
LI_RELOAD_Y = 0x02, /* Reload index register Y */ LI_RELOAD_Y = 0x02, /* Reload index register Y */
LI_REMOVE = 0x04, /* Load may be removed */ LI_REMOVE = 0x04, /* Load may be removed */
LI_DUP_LOAD = 0x08, /* Duplicate load */ LI_DONT_REMOVE = 0x08, /* Load may not be removed */
LI_DUP_LOAD = 0x10, /* Duplicate load */
} LI_FLAGS; } LI_FLAGS;
/* Structure that tells us how to load the lhs values */ /* Structure that tells us how to load the lhs values */
@@ -245,6 +246,18 @@ static void AdjustLoadInfo (LoadInfo* LI, int Index, int Change)
static void HonourUseAndChg (LoadRegInfo* RI, unsigned Reg, const CodeEntry* E)
/* Honour use and change flags for an instruction */
{
if (E->Chg & Reg) {
ClearLoadRegInfo (RI);
} else if ((E->Use & Reg) && RI->LoadIndex >= 0) {
RI->Flags |= LI_DONT_REMOVE;
}
}
static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I) static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I)
/* Track loads for a code entry */ /* Track loads for a code entry */
{ {
@@ -349,15 +362,9 @@ static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I)
ClearLoadRegInfo (&LI->Y); ClearLoadRegInfo (&LI->Y);
} else { } else {
if (E->Chg & REG_A) { HonourUseAndChg (&LI->A, REG_A, E);
ClearLoadRegInfo (&LI->A); HonourUseAndChg (&LI->X, REG_X, E);
} HonourUseAndChg (&LI->Y, REG_Y, E);
if (E->Chg & REG_X) {
ClearLoadRegInfo (&LI->X);
}
if (E->Chg & REG_Y) {
ClearLoadRegInfo (&LI->Y);
}
} }
} }
@@ -646,7 +653,7 @@ static void RemoveRegLoads (StackOpData* D, LoadInfo* LI)
/* Both registers may be loaded with one insn, but DelEntry will in this /* Both registers may be loaded with one insn, but DelEntry will in this
* case clear the other one. * case clear the other one.
*/ */
if (LI->A.Flags & LI_REMOVE) { if ((LI->A.Flags & (LI_REMOVE | LI_DONT_REMOVE)) == LI_REMOVE) {
if (LI->A.LoadIndex >= 0) { if (LI->A.LoadIndex >= 0) {
DelEntry (D, LI->A.LoadIndex); DelEntry (D, LI->A.LoadIndex);
} }
@@ -654,7 +661,7 @@ static void RemoveRegLoads (StackOpData* D, LoadInfo* LI)
DelEntry (D, LI->A.XferIndex); DelEntry (D, LI->A.XferIndex);
} }
} }
if (LI->X.Flags & LI_REMOVE) { if ((LI->X.Flags & (LI_REMOVE | LI_DONT_REMOVE)) == LI_REMOVE) {
if (LI->X.LoadIndex >= 0) { if (LI->X.LoadIndex >= 0) {
DelEntry (D, LI->X.LoadIndex); DelEntry (D, LI->X.LoadIndex);
} }
@@ -875,7 +882,7 @@ static unsigned Opt_tosshift (StackOpData* D, const char* Name)
AddStoreA (D); AddStoreA (D);
/* Be sure to setup IP after adding the stores, otherwise it will get /* Be sure to setup IP after adding the stores, otherwise it will get
* messed up. * messed up.
*/ */
D->IP = D->OpIndex+1; D->IP = D->OpIndex+1;

View File

@@ -1952,6 +1952,7 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */
type = CF_CONST; type = CF_CONST;
if ((Gen->Flags & GEN_NOPUSH) == 0) { if ((Gen->Flags & GEN_NOPUSH) == 0) {
g_push (ltype, 0); g_push (ltype, 0);
} else {
ltype |= CF_REG; /* Value is in register */ ltype |= CF_REG; /* Value is in register */
} }

View File

@@ -114,7 +114,6 @@ static void Usage (void)
" --config name\t\tUse linker config file\n" " --config name\t\tUse linker config file\n"
" --dbgfile name\tGenerate debug information\n" " --dbgfile name\tGenerate debug information\n"
" --define sym=val\tDefine a symbol\n" " --define sym=val\tDefine a symbol\n"
" --dump-config name\tDump a builtin configuration\n"
" --end-group\t\tEnd a library group\n" " --end-group\t\tEnd a library group\n"
" --force-import sym\tForce an import of symbol `sym'\n" " --force-import sym\tForce an import of symbol `sym'\n"
" --help\t\tHelp (this text)\n" " --help\t\tHelp (this text)\n"

View File

@@ -9,6 +9,9 @@ int main (int argc, char* argv[])
for (I = 0; I < argc; ++I) { for (I = 0; I < argc; ++I) {
printf ("argv[%2d]: \"%s\"\n", I, argv[I]); printf ("argv[%2d]: \"%s\"\n", I, argv[I]);
} }
printf ("\n");
getchar ();
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@@ -40,6 +40,7 @@ int main(void)
printf("is'a a XL/XE, %s, Rev. %d\n",palntsc ? "PAL" : "NTSC",minor); printf("is'a a XL/XE, %s, Rev. %d\n",palntsc ? "PAL" : "NTSC",minor);
break; break;
} }
printf("hit <RETURN> to continure...\n"); printf("hit <RETURN> to continue...\n");
c = getchar(); c = getchar();
return 0;
} }

37
testcode/lib/atari/sys.c Normal file
View File

@@ -0,0 +1,37 @@
/*
* testprogram for _sys() function on Atari
*
* 17-Sep-2013, chris@groessler.org
*
* uses PUTCHR IOCB function to display a string
*/
#include <atari.h>
#include <6502.h>
#include <conio.h>
static struct regs regs;
static struct __iocb *iocb = &IOCB; /* use IOCB #0 */
static char message[] = "I'm the sys test text\n";
int main(void)
{
/* setup IOCB for CIO call */
iocb->buffer = message;
iocb->buflen = sizeof(message) - 1;
iocb->command = IOCB_PUTCHR;
/* setup input registers */
regs.x = 0; /* IOCB #0 */
regs.pc = 0xe456; /* CIOV */
/* call CIO */
_sys(&regs);
if (regs.y != 1)
cprintf("CIO error 0x%02\r\n", regs.y);
cgetc();
return 0;
}

View File

@@ -20,6 +20,10 @@
#define DRIVERNAME "a2e.auxmem.emd" #define DRIVERNAME "a2e.auxmem.emd"
#elif defined(__APPLE2__) #elif defined(__APPLE2__)
#define DRIVERNAME "a2.auxmem.emd" #define DRIVERNAME "a2.auxmem.emd"
#elif defined(__ATARIXL__)
#define DRIVERNAME "atrx130.emd"
#elif defined(__ATARI__)
#define DRIVERNAME "atr130.emd"
#else #else
#define DRIVERNAME "unknown" #define DRIVERNAME "unknown"
#error "Unknown target system" #error "Unknown target system"
@@ -63,6 +67,9 @@ static void cmp (unsigned page, register const unsigned* buf,
cprintf ("\r\nData mismatch in page $%04X at $%04X\r\n" cprintf ("\r\nData mismatch in page $%04X at $%04X\r\n"
"Data is $%04X (should be $%04X)\r\n", "Data is $%04X (should be $%04X)\r\n",
page, buf, *buf, num); page, buf, *buf, num);
#ifdef __ATARI__
cgetc ();
#endif
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
} }
@@ -84,6 +91,9 @@ int main (void)
if (Res != EM_ERR_OK) { if (Res != EM_ERR_OK) {
cprintf ("Error in em_load_driver: %u\r\n", Res); cprintf ("Error in em_load_driver: %u\r\n", Res);
cprintf ("os: %u, %s\r\n", _oserror, _stroserror (_oserror)); cprintf ("os: %u, %s\r\n", _oserror, _stroserror (_oserror));
#ifdef __ATARI__
cgetc ();
#endif
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
atexit (cleanup); atexit (cleanup);
@@ -195,6 +205,10 @@ int main (void)
/* Success */ /* Success */
cprintf ("\r\nPassed!\r\n"); cprintf ("\r\nPassed!\r\n");
#ifdef __ATARI__
cgetc ();
#endif
return 0; return 0;
} }

24
testcode/lib/exec-test1.c Normal file
View File

@@ -0,0 +1,24 @@
/*
** These programs test CC65's exec() program-chaining function.
** exec-test1 runs exec-test2 -- that tests the loading and starting of another
** program. Then, exec-test2 runs arg-test -- that tests command-line argument
** passing.
**
** 2013-08-24, Greg King
*/
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <conio.h>
int main (void) {
clrscr ();
cprintf ("\nExec-test #1 -- launching #2...\r\n");
exec ("exec-test2", "");
cprintf ("\nFailed to find #2:\r\n %s.\r\n", _stroserror (_oserror));
cgetc ();
return _oserror;
}

23
testcode/lib/exec-test2.c Normal file
View File

@@ -0,0 +1,23 @@
/*
** These programs test CC65's exec() program-chaining function.
** exec-test1 runs exec-test2 -- that tests the loading and starting of another
** program. Then, exec-test2 runs arg-test -- that tests command-line argument
** passing.
**
** 2013-08-24, Greg King
*/
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <conio.h>
int main (void) {
cprintf ("\nExec-test #2 -- launching arg-test...\r\n\n");
exec ("arg-test", "arg1 arg2 \"\" arg4");
cprintf ("\nFailed to find arg-test:\r\n %s.\r\n", _stroserror (_oserror));
cgetc ();
return _oserror;
}

View File

@@ -5,12 +5,22 @@
#define VERSION_ASC "0.90" #define VERSION_ASC "0.90"
#define KEYB_BUFSZ 80
#define PROMPT ">>> "
#ifdef __ATARI__ #ifdef __ATARI__
#define UPPERCASE /* define (e.g. for Atari) to convert filenames etc. to upper case */ #define UPPERCASE /* define (e.g. for Atari) to convert filenames etc. to upper case */
#define HAVE_SUBDIRS
#endif #endif
#ifdef __APPLE2__
#define HAVE_SUBDIRS
#endif
#ifdef __CC65__
#define CHECK_SP
#endif
#define KEYB_BUFSZ 80
#define PROMPT ">>> "
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -19,6 +29,7 @@
#ifndef __CC65__ #ifndef __CC65__
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/param.h> #include <sys/param.h>
#define HAVE_SUBDIRS
#else #else
#define MAXPATHLEN 64 #define MAXPATHLEN 64
#endif #endif
@@ -26,6 +37,10 @@
#include <fcntl.h> #include <fcntl.h>
#include <dirent.h> #include <dirent.h>
#ifdef CHECK_SP
extern unsigned int getsp(void); /* comes from getsp.s */
#endif
#define CMD_NOTHING 0 #define CMD_NOTHING 0
#define CMD_INVALID 1 #define CMD_INVALID 1
#define CMD_HELP 2 #define CMD_HELP 2
@@ -38,7 +53,10 @@
#define CMD_RENAME 9 #define CMD_RENAME 9
#define CMD_COPY 10 #define CMD_COPY 10
#define CMD_PWD 11 #define CMD_PWD 11
#define CMD_CLS 12
#define CMD_VERBOSE 13
static unsigned char verbose;
static unsigned char terminate; static unsigned char terminate;
static unsigned char cmd; static unsigned char cmd;
static unsigned char *cmd_asc, *arg1, *arg2, *arg3; static unsigned char *cmd_asc, *arg1, *arg2, *arg3;
@@ -56,11 +74,13 @@ struct cmd_table {
{ "ls", CMD_LS }, { "ls", CMD_LS },
{ "dir", CMD_LS }, { "dir", CMD_LS },
{ "md", CMD_MKDIR }, { "md", CMD_MKDIR },
#ifdef HAVE_SUBDIRS
{ "mkdir", CMD_MKDIR }, { "mkdir", CMD_MKDIR },
{ "rd", CMD_RMDIR }, { "rd", CMD_RMDIR },
{ "rmdir", CMD_RMDIR }, { "rmdir", CMD_RMDIR },
{ "cd", CMD_CHDIR }, { "cd", CMD_CHDIR },
{ "chdir", CMD_CHDIR }, { "chdir", CMD_CHDIR },
#endif
{ "rm", CMD_RM }, { "rm", CMD_RM },
{ "del", CMD_RM }, { "del", CMD_RM },
{ "cp", CMD_COPY }, { "cp", CMD_COPY },
@@ -68,6 +88,10 @@ struct cmd_table {
{ "mv", CMD_RENAME }, { "mv", CMD_RENAME },
{ "ren", CMD_RENAME }, { "ren", CMD_RENAME },
{ "pwd", CMD_PWD }, { "pwd", CMD_PWD },
#ifdef __ATARI__
{ "cls", CMD_CLS },
#endif
{ "verbose", CMD_VERBOSE },
{ NULL, 0 } { NULL, 0 }
}; };
@@ -82,6 +106,22 @@ static void get_command(void)
{ {
unsigned char i = 0; unsigned char i = 0;
#ifdef CHECK_SP
static char firstcall = 1;
static unsigned int good_sp;
unsigned int sp;
if (firstcall)
sp = good_sp = getsp();
else
sp = getsp();
if (sp != good_sp) {
printf("SP: 0x%04X ***MISMATCH*** 0x%04X\n", sp, good_sp);
}
else if (verbose)
printf("SP: 0x%04X\n", sp);
#endif
arg1 = arg2 = arg3 = NULL; arg1 = arg2 = arg3 = NULL;
/* issue prompt */ /* issue prompt */
@@ -132,6 +172,10 @@ static void cmd_help(void)
puts("cd, chdir - change directory or drive"); puts("cd, chdir - change directory or drive");
puts("md, mkdir - make directory or drive"); puts("md, mkdir - make directory or drive");
puts("rd, rmdir - remove directory or drive"); puts("rd, rmdir - remove directory or drive");
#ifdef __ATARI__
puts("cls - clear screen");
#endif
puts("verbose - set verbosity level");
puts("sorry, you cannot start programs here"); puts("sorry, you cannot start programs here");
} }
@@ -173,6 +217,8 @@ static void cmd_ls(void)
else else
arg = "."; arg = ".";
if (verbose)
printf("Buffer addr: %p\n", arg);
dir = opendir(arg); dir = opendir(arg);
#ifdef __ATARI__ #ifdef __ATARI__
if (need_free) free(arg); if (need_free) free(arg);
@@ -203,6 +249,8 @@ static void cmd_rm(void)
printf("remove failed: %s\n", strerror(errno)); printf("remove failed: %s\n", strerror(errno));
} }
#ifdef HAVE_SUBDIRS
static void cmd_mkdir(void) static void cmd_mkdir(void)
{ {
if (!arg1 || arg2) { if (!arg1 || arg2) {
@@ -262,6 +310,8 @@ static void cmd_pwd(void)
printf("malloc %u bytes failed: %s\n", MAXPATHLEN, strerror(errno)); printf("malloc %u bytes failed: %s\n", MAXPATHLEN, strerror(errno));
return; return;
} }
if (verbose)
printf("Buffer addr: %p\n", buf);
if (!getcwd(buf, MAXPATHLEN)) { if (!getcwd(buf, MAXPATHLEN)) {
printf("getcwd failed: %s\n", strerror(errno)); printf("getcwd failed: %s\n", strerror(errno));
free(buf); free(buf);
@@ -272,6 +322,8 @@ static void cmd_pwd(void)
free(buf); free(buf);
} }
#endif /* #ifdef HAVE_SUBDIRS */
static void cmd_rename(void) static void cmd_rename(void)
{ {
if (!arg2 || arg3) { if (!arg2 || arg3) {
@@ -309,6 +361,8 @@ static void cmd_copy(void)
printf("malloc %u bytes failed: %s\n", cpbuf_sz, strerror(errno)); printf("malloc %u bytes failed: %s\n", cpbuf_sz, strerror(errno));
return; return;
} }
if (verbose)
printf("Buffer addr: %p\n", buf);
while (1) { while (1) {
if (srcfd == -1) { if (srcfd == -1) {
@@ -349,6 +403,33 @@ static void cmd_copy(void)
if (dstfd >= 0) close(dstfd); if (dstfd >= 0) close(dstfd);
} }
#ifdef __ATARI__
static void cmd_cls(void)
{
printf("\f");
}
#endif
static void cmd_verbose(void)
{
unsigned long verb;
char *endptr;
if (!arg1 || arg2) {
puts("usage: verbose <level>");
return;
}
verb = strtoul(arg1, &endptr, 10);
if (verb > 255 || *endptr) {
puts("invalid verbosity level");
return;
}
verbose = verb;
printf("verbosity level set to %d\n", verbose);
}
static void run_command(void) static void run_command(void)
{ {
switch (cmd) { switch (cmd) {
@@ -359,12 +440,18 @@ static void run_command(void)
case CMD_QUIT: terminate = 1; return; case CMD_QUIT: terminate = 1; return;
case CMD_LS: cmd_ls(); return; case CMD_LS: cmd_ls(); return;
case CMD_RM: cmd_rm(); return; case CMD_RM: cmd_rm(); return;
#ifdef HAVE_SUBDIRS
case CMD_CHDIR: cmd_chdir(); return; case CMD_CHDIR: cmd_chdir(); return;
case CMD_MKDIR: cmd_mkdir(); return; case CMD_MKDIR: cmd_mkdir(); return;
case CMD_RMDIR: cmd_rmdir(); return; case CMD_RMDIR: cmd_rmdir(); return;
case CMD_PWD: cmd_pwd(); return; case CMD_PWD: cmd_pwd(); return;
#endif
case CMD_RENAME: cmd_rename(); return; case CMD_RENAME: cmd_rename(); return;
case CMD_COPY: cmd_copy(); return; case CMD_COPY: cmd_copy(); return;
#ifdef __ATARI__
case CMD_CLS: cmd_cls(); return;
#endif
case CMD_VERBOSE: cmd_verbose(); return;
} }
} }