mirror of https://github.com/cc65/cc65.git
Merge branch 'master' into fptest
This commit is contained in:
commit
46be595d41
|
@ -19,7 +19,7 @@ jobs:
|
|||
- shell: bash
|
||||
run: git config --global core.autocrlf input
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Do some simple style checks
|
||||
shell: bash
|
||||
|
@ -44,7 +44,7 @@ jobs:
|
|||
shell: bash
|
||||
run: make -j2 doc
|
||||
- name: Upload a documents snapshot.
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: docs
|
||||
path: ./html
|
||||
|
@ -54,7 +54,7 @@ jobs:
|
|||
make -j2 bin USER_CFLAGS=-Werror CROSS_COMPILE=x86_64-w64-mingw32-
|
||||
|
||||
build_windows:
|
||||
name: Build (Windows)
|
||||
name: Build and Test (Windows)
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
|
@ -62,10 +62,10 @@ jobs:
|
|||
run: git config --global core.autocrlf input
|
||||
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Add msbuild to PATH
|
||||
uses: microsoft/setup-msbuild@v1.1
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
- name: Build app (x86 debug)
|
||||
run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug -property:Platform=Win32
|
||||
|
@ -79,4 +79,14 @@ jobs:
|
|||
- name: Build app (x64 release)
|
||||
run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release -property:Platform=x64
|
||||
|
||||
- name: Build utils (MinGW)
|
||||
shell: cmd
|
||||
run: make -j2 util SHELL=cmd
|
||||
|
||||
- name: Build the platform libraries (make lib)
|
||||
shell: cmd
|
||||
run: make -j2 lib QUIET=1 SHELL=cmd
|
||||
|
||||
- name: Run the regression tests (make test)
|
||||
shell: cmd
|
||||
run: make test QUIET=1 SHELL=cmd
|
||||
|
|
|
@ -18,10 +18,10 @@ jobs:
|
|||
run: git config --global core.autocrlf input
|
||||
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Add msbuild to PATH
|
||||
uses: microsoft/setup-msbuild@v1.1
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
- name: Build app (debug)
|
||||
run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug
|
||||
|
@ -44,7 +44,7 @@ jobs:
|
|||
- shell: bash
|
||||
run: git config --global core.autocrlf input
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Do some simple style checks
|
||||
shell: bash
|
||||
|
@ -86,18 +86,18 @@ jobs:
|
|||
mv cc65.zip cc65-snapshot-win32.zip
|
||||
|
||||
- name: Upload a 32-bit Snapshot Zip
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cc65-snapshot-win32
|
||||
path: cc65-snapshot-win32.zip
|
||||
- name: Upload a 64-bit Snapshot Zip
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cc65-snapshot-win64
|
||||
path: cc65-snapshot-win64.zip
|
||||
|
||||
- name: Get the online documents repo.
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: cc65/doc
|
||||
# this token will expire, if it does, generate a new one as decribed in https://github.com/cc65/cc65/issues/2065
|
||||
|
@ -120,7 +120,7 @@ jobs:
|
|||
- name: Package offline documents.
|
||||
run: 7z a cc65-snapshot-docs.zip ./html/*.*
|
||||
- name: Upload a Documents Snapshot Zip
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cc65-snapshot-docs
|
||||
path: cc65-snapshot-docs.zip
|
||||
|
|
|
@ -30,7 +30,7 @@ jobs:
|
|||
run: mkdir ~/.cache-sha
|
||||
|
||||
- name: Cache SHA
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
id: check-sha
|
||||
with:
|
||||
path: ~/.cache-sha
|
||||
|
@ -43,11 +43,11 @@ jobs:
|
|||
|
||||
- name: Checkout source
|
||||
if: steps.check-sha.outputs.cache-hit != 'true'
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Add msbuild to PATH
|
||||
if: steps.check-sha.outputs.cache-hit != 'true'
|
||||
uses: microsoft/setup-msbuild@v1.1
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
- name: Build app (MSVC debug)
|
||||
if: steps.check-sha.outputs.cache-hit != 'true'
|
||||
|
|
|
@ -9,7 +9,7 @@ For details look at the [Website](https://cc65.github.io).
|
|||
|
||||
Project founders:
|
||||
|
||||
* John R. Dunning: original implementation of the C compiler and runtime library, Atari hosted
|
||||
* John R. Dunning: [original implementation](https://public.websites.umich.edu/~archive/atari/8bit/Languages/Cc65/) of the C compiler and runtime library, Atari hosted
|
||||
* Ullrich von Bassewitz:
|
||||
* move the code to modern systems
|
||||
* rewrite most parts of the compiler
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
# kim1-mtu60k.cfg (4k)
|
||||
#
|
||||
# for expanded KIM-1 w/ K-1008 Graphics and 60K RAM
|
||||
#
|
||||
# ld65 --config kim1-mtu60k.cfg -o <prog>.bin <prog>.o
|
||||
|
||||
FEATURES {
|
||||
STARTADDRESS: default = $2000;
|
||||
CONDES: segment = STARTUP,
|
||||
type = constructor,
|
||||
label = __CONSTRUCTOR_TABLE__,
|
||||
count = __CONSTRUCTOR_COUNT__;
|
||||
CONDES: segment = STARTUP,
|
||||
type = destructor,
|
||||
label = __DESTRUCTOR_TABLE__,
|
||||
count = __DESTRUCTOR_COUNT__;
|
||||
}
|
||||
|
||||
SYMBOLS {
|
||||
__STACKSIZE__: type = weak, value = $0080; # 128 byte program stack
|
||||
__STARTADDRESS__: type = export, value = %S;
|
||||
}
|
||||
|
||||
MEMORY {
|
||||
ZP: file = %O, define = yes, start = $0000, size = $00EE;
|
||||
CPUSTACK: file = "", define = yes, start = $0100, size = $0100;
|
||||
RAM: file = %O, define = yes, start = %S, size = $E000 - %S - __STACKSIZE__;
|
||||
MAINROM: file = "", define = yes, start = $E000, size = $1000;
|
||||
TOP: file = "", define = yes, start = $F000, size = $1000;
|
||||
}
|
||||
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp, define = yes;
|
||||
STARTUP: load = RAM, type = ro, define = yes;
|
||||
CODE: load = RAM, type = ro, define = yes;
|
||||
RODATA: load = RAM, type = ro, define = yes;
|
||||
ONCE: load = RAM, type = ro, define = yes;
|
||||
DATA: load = RAM, type = rw, define = yes;
|
||||
BSS: load = RAM, type = bss, define = yes;
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# kim1-mtu60k.cfg (4k)
|
||||
#
|
||||
# for expanded KIM-1 w/ K-1008 Graphics and 60K RAM
|
||||
#
|
||||
# ld65 --config kim1-mtu60k.cfg -o <prog>.bin <prog>.o
|
||||
|
||||
FEATURES {
|
||||
STARTADDRESS: default = $E000;
|
||||
CONDES: segment = STARTUP,
|
||||
type = constructor,
|
||||
label = __CONSTRUCTOR_TABLE__,
|
||||
count = __CONSTRUCTOR_COUNT__;
|
||||
CONDES: segment = STARTUP,
|
||||
type = destructor,
|
||||
label = __DESTRUCTOR_TABLE__,
|
||||
count = __DESTRUCTOR_COUNT__;
|
||||
}
|
||||
|
||||
SYMBOLS {
|
||||
__STACKSIZE__: type = weak, value = $0080; # 128 byte program stack
|
||||
__STARTADDRESS__: type = export, value = %S;
|
||||
}
|
||||
|
||||
MEMORY {
|
||||
ZP: file = %O, define = yes, start = $0000, size = $00EE;
|
||||
CPUSTACK: file = "", define = yes, start = $0100, size = $0100;
|
||||
RAM: file = %O, define = yes, start = $2000, size = $E000 - $2000 - __STACKSIZE__;
|
||||
MAINROM: file = "", define = yes, start = $E000, size = $1000;
|
||||
TOP: file = "", define = yes, start = $F000, size = $1000;
|
||||
}
|
||||
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp, define = yes;
|
||||
STARTUP: load = RAM, type = ro, define = yes;
|
||||
CODE: load = RAM, type = ro, define = yes;
|
||||
RODATA: load = RAM, type = ro, define = yes;
|
||||
ONCE: load = RAM, type = ro, define = yes;
|
||||
DATA: load = RAM, type = rw, define = yes;
|
||||
BSS: load = RAM, type = bss, define = yes;
|
||||
}
|
||||
|
|
@ -62,7 +62,7 @@ Special locations:
|
|||
</descrip><p>
|
||||
|
||||
While running <tt/main()/ the Language Card bank 2 is enabled for read access.
|
||||
However while running module constructors/destructors the Language Card is disabled.
|
||||
However while running module constructors the Language Card is disabled.
|
||||
|
||||
Enabling the Language Card allows to use it as additional memory for cc65
|
||||
generated code. However code is never automatically placed there. Rather code
|
||||
|
|
|
@ -63,7 +63,7 @@ Special locations:
|
|||
</descrip><p>
|
||||
|
||||
While running <tt/main()/ the Language Card bank 2 is enabled for read access.
|
||||
However while running module constructors/destructors the Language Card is disabled.
|
||||
However while running module constructors the Language Card is disabled.
|
||||
|
||||
Enabling the Language Card allows to use it as additional memory for cc65
|
||||
generated code. However code is never automatically placed there. Rather code
|
||||
|
|
|
@ -86,6 +86,10 @@ extern FILE* stderr;
|
|||
# define FILENAME_MAX (80+1)
|
||||
#elif defined(__TELESTRAT__)
|
||||
# define FILENAME_MAX (50+1)
|
||||
#elif defined(__SIM6502__)
|
||||
# define FILENAME_MAX (1024+1)
|
||||
#elif defined(__SIM65C02__)
|
||||
# define FILENAME_MAX (1024+1)
|
||||
#else
|
||||
# define FILENAME_MAX (16+1)
|
||||
#endif
|
||||
|
|
|
@ -40,12 +40,15 @@ _exit: ldx #<exit
|
|||
lda #>exit
|
||||
jsr reset ; Setup RESET vector
|
||||
|
||||
; Switch in ROM, in case it wasn't already switched in by a RESET.
|
||||
bit $C082
|
||||
; Switch in LC bank 2 for R/O in case it was switched out by a RESET.
|
||||
bit $C080
|
||||
|
||||
; Call the module destructors.
|
||||
jsr donelib
|
||||
|
||||
; Switch in ROM.
|
||||
bit $C082
|
||||
|
||||
; Restore the original RESET vector.
|
||||
exit: ldx #$02
|
||||
: lda rvsave,x
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
.export _statvfs
|
||||
.import _dio_query_sectsize
|
||||
.import mli_file_info, pushax, popax, popptr1
|
||||
.import mli_file_info, pushax, popax, popptr1, pushptr1
|
||||
.include "zeropage.inc"
|
||||
.include "apple2.inc"
|
||||
.include "errno.inc"
|
||||
|
@ -45,9 +45,7 @@ _statvfs:
|
|||
sty vol_sep ; Register '/' index
|
||||
lda #$00
|
||||
sta (ptr1),y ; Cut pathname at first slash
|
||||
: lda ptr1
|
||||
ldx ptr1+1
|
||||
jsr pushax
|
||||
: jsr pushptr1
|
||||
|
||||
jsr mli_file_info
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
.import findfreeiocb
|
||||
.import incsp4
|
||||
.import ldaxysp,addysp
|
||||
.import ___oserror
|
||||
.import ___oserror, returnFFFF
|
||||
.ifdef UCASE_FILENAME
|
||||
.import ucase_fn
|
||||
.endif
|
||||
|
@ -39,9 +39,7 @@ parmok: jsr findfreeiocb
|
|||
lda #<EMFILE ; "too many open files"
|
||||
seterr: jsr ___directerrno
|
||||
jsr incsp4 ; clean up stack
|
||||
lda #$FF
|
||||
tax
|
||||
rts ; return -1
|
||||
jmp returnFFFF
|
||||
|
||||
; process the mode argument
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
.export _cbm_read
|
||||
.importzp ptr1, ptr2, ptr3, tmp1
|
||||
.import popax, popa
|
||||
.import popax, popa, returnFFFF
|
||||
.import ___oserror
|
||||
|
||||
|
||||
|
@ -107,7 +107,4 @@ _cbm_read:
|
|||
; CHKIN failed
|
||||
|
||||
@E1: sta ___oserror
|
||||
lda #$FF
|
||||
tax
|
||||
rts ; return -1
|
||||
|
||||
jmp returnFFFF
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
.export _cbm_write
|
||||
.importzp ptr1, ptr2, ptr3
|
||||
.import popax, popa
|
||||
.import popax, popa, returnFFFF
|
||||
.import ___oserror
|
||||
|
||||
|
||||
|
@ -88,7 +88,4 @@ _cbm_write:
|
|||
; Error entry, error code is in A
|
||||
|
||||
@E2: sta ___oserror
|
||||
lda #$FF
|
||||
tax
|
||||
rts ; return -1
|
||||
|
||||
jmp returnFFFF
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
.import _strlower, _strlen
|
||||
|
||||
.macpack generic
|
||||
.macpack cpu
|
||||
|
||||
; ----------------------------------------------------------------------------
|
||||
; We will store variables into the register bank in the zeropage. Define
|
||||
|
@ -37,7 +38,11 @@ FCount = ptr2
|
|||
|
||||
GetFormatChar:
|
||||
ldy #0
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
lda (Format)
|
||||
.else
|
||||
lda (Format),y
|
||||
.endif
|
||||
IncFormatPtr:
|
||||
inc Format
|
||||
bne @L1
|
||||
|
@ -110,7 +115,11 @@ GetIntArg:
|
|||
lda (ArgList),y
|
||||
tax
|
||||
dey
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
lda (ArgList)
|
||||
.else
|
||||
lda (ArgList),y
|
||||
.endif
|
||||
rts
|
||||
|
||||
; ----------------------------------------------------------------------------
|
||||
|
@ -135,9 +144,9 @@ ReadInt:
|
|||
pha ; Save digit value
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
asl ptr1
|
||||
asl a
|
||||
rol ptr1+1 ; * 2
|
||||
asl ptr1
|
||||
asl a
|
||||
rol ptr1+1 ; * 4, assume carry clear
|
||||
adc ptr1
|
||||
sta ptr1
|
||||
|
@ -265,10 +274,16 @@ Save: lda regbank,y
|
|||
; Initialize the output counter in the output descriptor to zero
|
||||
|
||||
lda #0
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
sta (OutData)
|
||||
ldy #$01
|
||||
sta (OutData),y
|
||||
.else
|
||||
tay
|
||||
sta (OutData),y
|
||||
iny
|
||||
sta (OutData),y
|
||||
.endif
|
||||
|
||||
; Get the output function from the output descriptor and remember it
|
||||
|
||||
|
@ -338,7 +353,11 @@ MainLoop:
|
|||
sta (sp),y
|
||||
dey
|
||||
lda FCount
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
sta (sp)
|
||||
.else
|
||||
sta (sp),y
|
||||
.endif
|
||||
jsr CallOutFunc ; Call the output function
|
||||
|
||||
; We're back from out(), or we didn't call it. Check for end of string.
|
||||
|
@ -551,10 +570,16 @@ CheckCount:
|
|||
jsr GetIntArg
|
||||
sta ptr1
|
||||
stx ptr1+1 ; Get user supplied pointer
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
lda (OutData) ; Low byte of OutData->ccount
|
||||
sta (ptr1)
|
||||
ldy #1
|
||||
.else
|
||||
ldy #0
|
||||
lda (OutData),y ; Low byte of OutData->ccount
|
||||
sta (ptr1),y
|
||||
iny
|
||||
.endif
|
||||
lda (OutData),y ; High byte of OutData->ccount
|
||||
sta (ptr1),y
|
||||
jmp MainLoop ; Done
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
;
|
||||
; Colin Leroy-Mira, 2024
|
||||
;
|
||||
; Helper to check for file opened, not eof, not ferror
|
||||
; Expects file pointer in ptr1,
|
||||
; Returns with Z flag set if everything is OK,
|
||||
; Destroys A, X, Y,
|
||||
; Sets file flags in A
|
||||
;
|
||||
|
||||
.export checkferror
|
||||
.importzp ptr1
|
||||
|
||||
.include "_file.inc"
|
||||
|
||||
checkferror:
|
||||
ldy #_FILE::f_flags
|
||||
lda (ptr1),y
|
||||
tax
|
||||
and #(_FOPEN|_FERROR|_FEOF); Check for file open, error/eof
|
||||
tay
|
||||
txa
|
||||
cpy #_FOPEN
|
||||
rts
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
.export _fclose
|
||||
|
||||
.import _close
|
||||
.import _close, ___directerrno
|
||||
.importzp ptr1
|
||||
|
||||
.include "errno.inc"
|
||||
|
@ -31,10 +31,7 @@
|
|||
; File is not open
|
||||
|
||||
lda #EINVAL
|
||||
jsr ___seterrno
|
||||
lda #$FF ; Return -1
|
||||
tax
|
||||
rts
|
||||
jmp ___directerrno
|
||||
|
||||
; File is open. Reset the flags and close the file.
|
||||
|
||||
|
@ -47,4 +44,3 @@
|
|||
jmp _close ; Will set errno and return an error flag
|
||||
|
||||
.endproc
|
||||
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
** fgetc.c
|
||||
**
|
||||
** (C) Copyright 1998, 2002 Ullrich von Bassewitz (uz@cc65.org)
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "_file.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
int __fastcall__ fgetc (register FILE* f)
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
/* Check if the file is open or if there is an error condition */
|
||||
if ((f->f_flags & _FOPEN) == 0 || (f->f_flags & (_FERROR | _FEOF)) != 0) {
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* If we have a pushed back character, return it */
|
||||
if (f->f_flags & _FPUSHBACK) {
|
||||
f->f_flags &= ~_FPUSHBACK;
|
||||
return f->f_pushback;
|
||||
}
|
||||
|
||||
/* Read one byte */
|
||||
switch (read (f->f_fd, &c, 1)) {
|
||||
|
||||
case -1:
|
||||
/* Error */
|
||||
f->f_flags |= _FERROR;
|
||||
return EOF;
|
||||
|
||||
case 0:
|
||||
/* EOF */
|
||||
f->f_flags |= _FEOF;
|
||||
return EOF;
|
||||
|
||||
default:
|
||||
/* Char read */
|
||||
return c;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
;
|
||||
; Colin Leroy-Mira, 2024
|
||||
;
|
||||
; int __fastcall__ fgetc (register FILE* f)
|
||||
;
|
||||
|
||||
.export _fgetc
|
||||
.import _read, checkferror
|
||||
.import pusha0, pushax, popptr1, incsp2, returnFFFF
|
||||
.importzp ptr1
|
||||
|
||||
.include "stdio.inc"
|
||||
.include "_file.inc"
|
||||
|
||||
.macpack cpu
|
||||
|
||||
_fgetc:
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
jsr pushax ; Backup our ptr
|
||||
|
||||
jsr checkferror
|
||||
bne ret_eof
|
||||
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
bit #_FPUSHBACK ; Check for pushed back char
|
||||
beq do_read
|
||||
.else
|
||||
tax
|
||||
and #_FPUSHBACK ; Check for pushed back char
|
||||
beq do_read
|
||||
txa
|
||||
.endif
|
||||
|
||||
and #<(~_FPUSHBACK) ; Reset flag
|
||||
sta (ptr1),y
|
||||
|
||||
.assert _FILE::f_pushback = _FILE::f_flags+1, error
|
||||
iny
|
||||
jsr incsp2 ; Drop our ptr copy
|
||||
lda (ptr1),y ; Return pushed back char
|
||||
ldx #$00
|
||||
rts
|
||||
|
||||
do_read:
|
||||
; Push _read parameters
|
||||
ldy #_FILE::f_fd
|
||||
lda (ptr1),y
|
||||
jsr pusha0
|
||||
|
||||
lda #<c
|
||||
ldx #>c
|
||||
jsr pushax
|
||||
|
||||
lda #$01
|
||||
ldx #$00
|
||||
|
||||
; Read
|
||||
jsr _read
|
||||
|
||||
; Check for errors
|
||||
cmp #$00
|
||||
beq set_feof
|
||||
|
||||
cmp #<(-1)
|
||||
beq set_ferror
|
||||
|
||||
jsr incsp2
|
||||
; Return char
|
||||
ldx #$00
|
||||
lda c
|
||||
rts
|
||||
|
||||
ret_eof:
|
||||
jsr incsp2
|
||||
jmp returnFFFF
|
||||
|
||||
set_ferror:
|
||||
lda #_FERROR
|
||||
bne set_err
|
||||
set_feof:
|
||||
lda #_FEOF
|
||||
set_err:
|
||||
pha
|
||||
jsr popptr1
|
||||
pla
|
||||
ldy #_FILE::f_flags
|
||||
ora (ptr1),y
|
||||
sta (ptr1),y
|
||||
jmp returnFFFF
|
||||
|
||||
.bss
|
||||
|
||||
c: .res 1
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
** Ullrich von Bassewitz, 11.08.1998
|
||||
**
|
||||
** char* fgets (char* s, int size, FILE* f);
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "_file.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
char* __fastcall__ fgets (char* s, unsigned size, register FILE* f)
|
||||
{
|
||||
register char* p = s;
|
||||
unsigned i;
|
||||
int c;
|
||||
|
||||
if (size == 0) {
|
||||
/* Invalid size */
|
||||
return (char*) _seterrno (EINVAL);
|
||||
}
|
||||
|
||||
/* Read input */
|
||||
i = 0;
|
||||
while (--size) {
|
||||
|
||||
/* Get next character */
|
||||
if ((c = fgetc (f)) == EOF) {
|
||||
/* Error or EOF */
|
||||
if ((f->f_flags & _FERROR) != 0 || i == 0) {
|
||||
/* ERROR or EOF on first char */
|
||||
*p = '\0';
|
||||
return 0;
|
||||
} else {
|
||||
/* EOF with data already read */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* One char more */
|
||||
*p = c;
|
||||
++p;
|
||||
++i;
|
||||
|
||||
/* Stop at end of line */
|
||||
if ((char)c == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Terminate the string */
|
||||
*p = '\0';
|
||||
|
||||
/* Done */
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
;
|
||||
; Colin Leroy-Mira, 2024
|
||||
;
|
||||
; char* __fastcall__ fgets (char* s, unsigned size, register FILE* f)
|
||||
;
|
||||
|
||||
.export _fgets
|
||||
.import _fgetc, popptr1, pushptr1, popax, pushax, return0, ___errno
|
||||
.importzp ptr1, ptr4
|
||||
|
||||
.include "errno.inc"
|
||||
.include "stdio.inc"
|
||||
.include "_file.inc"
|
||||
|
||||
.macpack cpu
|
||||
|
||||
terminate_ptr:
|
||||
lda #$00
|
||||
tax
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
sta (ptr4)
|
||||
.else
|
||||
tay
|
||||
sta (ptr4),y
|
||||
.endif
|
||||
rts
|
||||
|
||||
_fgets:
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
|
||||
jsr popax
|
||||
sta size
|
||||
stx size+1
|
||||
|
||||
jsr popax
|
||||
sta ptr4
|
||||
stx ptr4+1
|
||||
sta buf
|
||||
stx buf+1
|
||||
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
stz didread
|
||||
.else
|
||||
lda #$00 ; We have read nothing yet
|
||||
sta didread
|
||||
.endif
|
||||
|
||||
; Check size
|
||||
lda size
|
||||
ora size+1
|
||||
bne read_loop
|
||||
lda #EINVAL
|
||||
sta ___errno
|
||||
jmp return0
|
||||
|
||||
read_loop:
|
||||
lda size ; Dec size
|
||||
bne :+
|
||||
dec size+1
|
||||
: dec size
|
||||
|
||||
bne :+ ; Check bound
|
||||
ldx size+1
|
||||
beq done
|
||||
|
||||
: jsr pushptr1 ; Push ptr1 for backup and load it to AX for fgetc
|
||||
jsr _fgetc ; Read a char
|
||||
|
||||
pha
|
||||
jsr popptr1 ; Get ptr1 back
|
||||
pla
|
||||
|
||||
cpx #<EOF
|
||||
beq got_eof
|
||||
|
||||
ldy #$01
|
||||
sty didread ; We read at least one char
|
||||
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
sta (ptr4)
|
||||
.else
|
||||
dey
|
||||
sta (ptr4),y
|
||||
.endif
|
||||
|
||||
inc ptr4
|
||||
bne :+
|
||||
inc ptr4+1
|
||||
|
||||
: cmp #$0A ; Stop at \n
|
||||
beq done
|
||||
bne read_loop
|
||||
|
||||
got_eof:
|
||||
lda didread
|
||||
beq stopped_at_first_char
|
||||
ldy #_FILE::f_flags
|
||||
lda (ptr1),y
|
||||
and #_FERROR
|
||||
bne stopped_at_first_char
|
||||
|
||||
done:
|
||||
jsr terminate_ptr
|
||||
ldx #>buf
|
||||
lda #<buf
|
||||
rts
|
||||
|
||||
stopped_at_first_char:
|
||||
jmp terminate_ptr
|
||||
|
||||
.bss
|
||||
|
||||
c: .res 1
|
||||
buf: .res 2
|
||||
size: .res 2
|
||||
didread:.res 1
|
|
@ -5,7 +5,7 @@
|
|||
;
|
||||
|
||||
.export _clearerr, _feof, _ferror, _fileno, _fflush
|
||||
.import return0
|
||||
.import return0, ___directerrno
|
||||
.importzp ptr1
|
||||
|
||||
.include "_file.inc"
|
||||
|
@ -78,10 +78,7 @@ err: rts
|
|||
; If the file is not valid, fileno must set errno and return -1
|
||||
|
||||
error: lda #<EBADF
|
||||
jsr ___seterrno
|
||||
lda #$FF
|
||||
tax
|
||||
rts
|
||||
jmp ___directerrno
|
||||
.endproc
|
||||
|
||||
;
|
||||
|
@ -89,5 +86,3 @@ error: lda #<EBADF
|
|||
;
|
||||
|
||||
_fflush = return0
|
||||
|
||||
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
** fputc.c
|
||||
**
|
||||
** Ullrich von Bassewitz, 02.06.1998
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "_file.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
int __fastcall__ fputc (int c, register FILE* f)
|
||||
{
|
||||
/* Check if the file is open or if there is an error condition */
|
||||
if ((f->f_flags & _FOPEN) == 0 || (f->f_flags & (_FERROR | _FEOF)) != 0) {
|
||||
goto ReturnEOF;
|
||||
}
|
||||
|
||||
/* Write the byte */
|
||||
if (write (f->f_fd, &c, 1) != 1) {
|
||||
/* Error */
|
||||
f->f_flags |= _FERROR;
|
||||
ReturnEOF:
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* Return the byte written */
|
||||
return c & 0xFF;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
;
|
||||
; Colin Leroy-Mira, 2024
|
||||
;
|
||||
; int __fastcall__ fputc (int c, FILE* f);
|
||||
;
|
||||
|
||||
.export _fputc
|
||||
.importzp ptr1
|
||||
.import _write, checkferror
|
||||
.import pushax, pusha0, popax, incsp2
|
||||
.import pushptr1, popptr1, returnFFFF
|
||||
|
||||
.include "stdio.inc"
|
||||
.include "_file.inc"
|
||||
|
||||
_fputc:
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
|
||||
jsr popax ; Get char, as we'll have
|
||||
sta c ; to return it anyway
|
||||
stx c+1
|
||||
|
||||
jsr checkferror
|
||||
bne ret_eof
|
||||
|
||||
jsr pushptr1 ; Backup fp pointer
|
||||
|
||||
; Push _write parameters
|
||||
ldy #_FILE::f_fd
|
||||
lda (ptr1),y
|
||||
jsr pusha0
|
||||
|
||||
lda #<c
|
||||
ldx #>c
|
||||
jsr pushax
|
||||
|
||||
lda #$01
|
||||
ldx #$00
|
||||
|
||||
; Write
|
||||
jsr _write
|
||||
|
||||
; Check for errors
|
||||
cmp #$01
|
||||
bne set_ferror
|
||||
|
||||
; Return char
|
||||
lda c
|
||||
ldx #$00
|
||||
jmp incsp2 ; Drop fp pointer copy
|
||||
|
||||
ret_eof:
|
||||
jmp returnFFFF
|
||||
|
||||
set_ferror:
|
||||
jsr popptr1
|
||||
lda #_FERROR
|
||||
ldy #_FILE::f_flags
|
||||
ora (ptr1),y
|
||||
sta (ptr1),y
|
||||
jmp returnFFFF
|
||||
|
||||
.bss
|
||||
|
||||
c: .res 2
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
** int fputs (const char* s, FILE* f);
|
||||
**
|
||||
** Ullrich von Bassewitz, 11.08.1998
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "_file.h"
|
||||
|
||||
|
||||
|
||||
int __fastcall__ fputs (const char* s, register FILE* f)
|
||||
{
|
||||
/* Check if the file is open or if there is an error condition */
|
||||
if ((f->f_flags & _FOPEN) == 0 || (f->f_flags & (_FERROR | _FEOF)) != 0) {
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* Write the string */
|
||||
return write (f->f_fd, s, strlen (s));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
;
|
||||
; Colin Leroy-Mira, 2024
|
||||
;
|
||||
; int __fastcall__ fputs (const char* s, register FILE* f)
|
||||
;
|
||||
|
||||
.export _fputs
|
||||
.importzp ptr1, ptr2
|
||||
.import _write, _strlen, checkferror
|
||||
.import swapstk, pushax, returnFFFF
|
||||
|
||||
.include "stdio.inc"
|
||||
.include "_file.inc"
|
||||
|
||||
_fputs:
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
|
||||
jsr checkferror
|
||||
bne ret_eof
|
||||
|
||||
; Push _write parameters
|
||||
ldy #_FILE::f_fd
|
||||
lda (ptr1),y
|
||||
ldx #$00
|
||||
jsr swapstk ; Push fd, get s
|
||||
|
||||
jsr pushax ; Push s
|
||||
|
||||
jsr _strlen ; Get length
|
||||
|
||||
; Write
|
||||
jmp _write
|
||||
|
||||
ret_eof:
|
||||
jmp returnFFFF
|
|
@ -20,6 +20,7 @@
|
|||
.include "_file.inc"
|
||||
|
||||
.macpack generic
|
||||
.macpack cpu
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Code
|
||||
|
@ -47,13 +48,21 @@
|
|||
|
||||
ldy #_FILE::f_flags
|
||||
lda (file),y
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
bit #_FOPEN ; Is the file open?
|
||||
.else
|
||||
and #_FOPEN ; Is the file open?
|
||||
.endif
|
||||
beq @L1 ; Branch if no
|
||||
|
||||
; Check if the stream is in an error state
|
||||
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
bit #_FERROR
|
||||
.else
|
||||
lda (file),y ; get file->f_flags again
|
||||
and #_FERROR
|
||||
.endif
|
||||
beq @L2
|
||||
|
||||
; File not open or in error state
|
||||
|
@ -65,11 +74,19 @@
|
|||
|
||||
; Remember if we have a pushed back character and reset the flag.
|
||||
|
||||
@L2: tax ; X = 0
|
||||
@L2: .if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
ldx #$00
|
||||
bit #_FPUSHBACK
|
||||
.else
|
||||
tax ; X = 0
|
||||
lda (file),y
|
||||
and #_FPUSHBACK
|
||||
.endif
|
||||
beq @L3
|
||||
|
||||
.if (.not .cpu .bitand ::CPU_ISET_65SC02)
|
||||
lda (file),y
|
||||
.endif
|
||||
and #<~_FPUSHBACK
|
||||
sta (file),y ; file->f_flags &= ~_FPUSHBACK;
|
||||
inx ; X = 1
|
||||
|
@ -118,12 +135,20 @@
|
|||
; Copy the buffer pointer into ptr1, and increment the pointer value passed
|
||||
; to read() by one, so read() starts to store data at buf+1.
|
||||
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
lda (sp)
|
||||
sta ptr1
|
||||
add #1
|
||||
sta (sp)
|
||||
ldy #1
|
||||
.else
|
||||
ldy #0
|
||||
lda (sp),y
|
||||
sta ptr1
|
||||
add #1
|
||||
sta (sp),y
|
||||
iny
|
||||
.endif
|
||||
lda (sp),y
|
||||
sta ptr1+1
|
||||
adc #0
|
||||
|
@ -134,8 +159,12 @@
|
|||
|
||||
ldy #_FILE::f_pushback
|
||||
lda (file),y
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
sta (ptr1) ; *buf = file->f_pushback;
|
||||
.else
|
||||
ldy #0
|
||||
sta (ptr1),y ; *buf = file->f_pushback;
|
||||
.endif
|
||||
|
||||
; Restore the low byte of count and decrement count by one. This may result
|
||||
; in count being zero, so check for that.
|
||||
|
@ -210,4 +239,3 @@
|
|||
.bss
|
||||
save: .res 2
|
||||
pb: .res 1
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
.export _fwrite
|
||||
|
||||
.import _write
|
||||
.import pushax, incsp6, addysp, ldaxysp, pushwysp, return0
|
||||
.import pushax, pusha0, incsp6, addysp, ldaxysp, pushwysp, return0
|
||||
.import tosumulax, tosudivax
|
||||
|
||||
.importzp ptr1
|
||||
|
@ -16,6 +16,7 @@
|
|||
.include "errno.inc"
|
||||
.include "_file.inc"
|
||||
|
||||
.macpack cpu
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Code
|
||||
|
@ -33,7 +34,11 @@
|
|||
|
||||
ldy #_FILE::f_flags
|
||||
lda (ptr1),y
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
bit #_FOPEN
|
||||
.else
|
||||
and #_FOPEN ; Is the file open?
|
||||
.endif
|
||||
bne @L2 ; Branch if yes
|
||||
|
||||
; File not open
|
||||
|
@ -45,7 +50,9 @@
|
|||
|
||||
; Check if the stream is in an error state
|
||||
|
||||
@L2: lda (ptr1),y ; get file->f_flags again
|
||||
@L2: .if (.not .cpu .bitand ::CPU_ISET_65SC02)
|
||||
lda (ptr1),y ; get file->f_flags again
|
||||
.endif
|
||||
and #_FERROR
|
||||
bne @L1
|
||||
|
||||
|
@ -53,8 +60,7 @@
|
|||
|
||||
ldy #_FILE::f_fd
|
||||
lda (ptr1),y
|
||||
ldx #$00
|
||||
jsr pushax ; file->f_fd
|
||||
jsr pusha0 ; file->f_fd
|
||||
|
||||
ldy #9
|
||||
jsr pushwysp ; buf
|
||||
|
@ -123,4 +129,3 @@
|
|||
|
||||
.bss
|
||||
file: .res 2
|
||||
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
** gets.c
|
||||
**
|
||||
** Ullrich von Bassewitz, 11.08.1998
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "_file.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
char* __fastcall__ gets (char* s)
|
||||
{
|
||||
register char* p = s;
|
||||
int c;
|
||||
unsigned i = 0;
|
||||
|
||||
while (1) {
|
||||
|
||||
/* Get next character */
|
||||
if ((c = fgetc (stdin)) == EOF) {
|
||||
/* Error or EOF */
|
||||
*p = '\0';
|
||||
if (stdin->f_flags & _FERROR) {
|
||||
/* ERROR */
|
||||
return 0;
|
||||
} else {
|
||||
/* EOF */
|
||||
if (i) {
|
||||
return s;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* One char more. Newline ends the input */
|
||||
if ((char) c == '\n') {
|
||||
*p = '\0';
|
||||
break;
|
||||
} else {
|
||||
*p = c;
|
||||
++p;
|
||||
++i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Done */
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
;
|
||||
; Colin Leroy-Mira, 2024
|
||||
;
|
||||
; char* __fastcall__ gets (char* s)
|
||||
;
|
||||
|
||||
.export _gets
|
||||
.import _fgets, _stdin, popax, pushax
|
||||
.importzp ptr4
|
||||
|
||||
_gets:
|
||||
; Push buffer
|
||||
sta ptr4
|
||||
stx ptr4+1
|
||||
jsr pushax
|
||||
|
||||
; Push size (there's no limit!)
|
||||
lda #$FF
|
||||
tax
|
||||
jsr pushax
|
||||
|
||||
lda _stdin
|
||||
ldx _stdin+1
|
||||
|
||||
jsr _fgets
|
||||
|
||||
; Check return value
|
||||
bne :+
|
||||
cpx #$00
|
||||
bne :+
|
||||
rts
|
||||
|
||||
: ; At least one byte written.
|
||||
jsr pushax ; Store returned pointer
|
||||
|
||||
; Remove \n if there is one.
|
||||
lda ptr4 ; _fgets returns with ptr4 at
|
||||
bne :+ ; end of buffer
|
||||
dec ptr4+1
|
||||
: dec ptr4
|
||||
lda (ptr4),y ; _fgets returns with Y=0
|
||||
cmp #$0A
|
||||
bne :+
|
||||
tya
|
||||
sta (ptr4),y ; Set terminator over \n
|
||||
|
||||
: jmp popax
|
|
@ -131,6 +131,7 @@ _malloc:
|
|||
sta ptr1
|
||||
bcc @L1
|
||||
inc ptr1+1
|
||||
beq OutOfHeapSpace ; if high byte's 0, we overflowed!
|
||||
@L1: ldx ptr1+1
|
||||
bne @L2
|
||||
cmp #HEAP_MIN_BLOCKSIZE+1
|
||||
|
@ -336,4 +337,3 @@ RetUserPtr:
|
|||
bcc @L9
|
||||
inx
|
||||
@L9: rts
|
||||
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
*/
|
||||
|
||||
|
||||
|
||||
int __fastcall__ posix_memalign (void** memptr, size_t alignment, size_t size)
|
||||
/* Allocate a block of memory with the given "size", which is aligned to a
|
||||
** memory address that is a multiple of "alignment". "alignment" MUST NOT be
|
||||
|
@ -64,20 +63,27 @@ int __fastcall__ posix_memalign (void** memptr, size_t alignment, size_t size)
|
|||
size_t rawsize;
|
||||
size_t uppersize;
|
||||
size_t lowersize;
|
||||
char err;
|
||||
register struct usedblock* b; /* points to raw Block */
|
||||
register struct usedblock* u; /* points to User block */
|
||||
register struct usedblock* p; /* Points to upper block */
|
||||
|
||||
/* Handle requests for zero-sized blocks */
|
||||
if (size == 0) {
|
||||
err_einval:
|
||||
err = EINVAL;
|
||||
err_out:
|
||||
*memptr = NULL;
|
||||
return EINVAL;
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Test alignment: is it a power of two? There must be only one bit set. */
|
||||
if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
|
||||
*memptr = NULL;
|
||||
return EINVAL;
|
||||
/* Test alignment: is it a power of two? There must be one and only one bit set. */
|
||||
if (alignment == 0) {
|
||||
goto err_einval;
|
||||
}
|
||||
|
||||
if (alignment & (alignment - 1)) {
|
||||
goto err_einval;
|
||||
}
|
||||
|
||||
/* Augment the block size up to the alignment, and allocate memory.
|
||||
|
@ -90,8 +96,8 @@ int __fastcall__ posix_memalign (void** memptr, size_t alignment, size_t size)
|
|||
|
||||
/* Handle out-of-memory */
|
||||
if (b == NULL) {
|
||||
*memptr = NULL;
|
||||
return ENOMEM;
|
||||
err = ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/* Create (and return) a new pointer that points to the user-visible
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
.import _malloc, _free
|
||||
.import searchenv, copyenvptr
|
||||
.import __environ, __envcount, __envsize
|
||||
.import return0
|
||||
.import return0, ___directerrno
|
||||
.import ptr1:zp, ptr2:zp, ptr3:zp, tmp1:zp
|
||||
|
||||
.include "errno.inc"
|
||||
|
@ -169,10 +169,7 @@ addentry:
|
|||
; Error entries
|
||||
|
||||
nomem: lda #ENOMEM
|
||||
error: jsr ___seterrno
|
||||
lda #$FF ; Return -1
|
||||
tax
|
||||
rts
|
||||
error: jmp ___directerrno
|
||||
|
||||
.endproc
|
||||
|
||||
|
@ -184,5 +181,3 @@ error: jsr ___seterrno
|
|||
|
||||
name: .addr 0 ; Pointer to name
|
||||
newsize: .byte 0 ; New environment size
|
||||
|
||||
|
||||
|
|
|
@ -1,112 +0,0 @@
|
|||
/*****************************************************************************/
|
||||
/* */
|
||||
/* realloc.c */
|
||||
/* */
|
||||
/* Change the size of an allocated memory block */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 1998-2004 Ullrich von Bassewitz */
|
||||
/* Wacholderweg 14 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* EMail: uz@musoftware.de */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
/* warranty. In no event will the authors be held liable for any damages */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* Permission is granted to anyone to use this software for any purpose, */
|
||||
/* including commercial applications, and to alter it and redistribute it */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||
/* claim that you wrote the original software. If you use this software */
|
||||
/* in a product, an acknowledgment in the product documentation would be */
|
||||
/* appreciated but is not required. */
|
||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <_heap.h>
|
||||
|
||||
|
||||
|
||||
void* __fastcall__ realloc (void* block, register size_t size)
|
||||
{
|
||||
register struct usedblock* b;
|
||||
struct usedblock* newblock;
|
||||
unsigned oldsize;
|
||||
unsigned newhptr;
|
||||
|
||||
/* Check the block parameter */
|
||||
if (!block) {
|
||||
/* Block is NULL, same as malloc */
|
||||
return malloc (size);
|
||||
}
|
||||
|
||||
/* Check the size parameter */
|
||||
if (size == 0) {
|
||||
/* Block is not NULL, but size is: free the block */
|
||||
free (block);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Make the internal used size from the given size */
|
||||
size += HEAP_ADMIN_SPACE;
|
||||
if (size < sizeof (struct freeblock)) {
|
||||
size = sizeof (struct freeblock);
|
||||
}
|
||||
|
||||
/* The word below the user block contains a pointer to the start of the
|
||||
** raw memory block. The first word of this raw memory block is the full
|
||||
** size of the block. Get a pointer to the real block, get the old block
|
||||
** size.
|
||||
*/
|
||||
b = (((struct usedblock*) block) - 1)->start;
|
||||
oldsize = b->size;
|
||||
|
||||
/* Is the block at the current heap top? */
|
||||
if (((unsigned) b) + oldsize == ((unsigned) __heapptr)) {
|
||||
/* Check if we've enough memory at the heap top */
|
||||
newhptr = ((unsigned) __heapptr) - oldsize + size;
|
||||
if (newhptr <= ((unsigned) __heapend)) {
|
||||
/* Ok, there's space enough */
|
||||
__heapptr = (unsigned*) newhptr;
|
||||
b->size = size;
|
||||
b->start = b;
|
||||
return block;
|
||||
}
|
||||
}
|
||||
|
||||
/* The given block was not located on top of the heap, or there's no
|
||||
** room left. Try to allocate a new block and copy the data.
|
||||
*/
|
||||
if (newblock = malloc (size)) {
|
||||
|
||||
/* Adjust the old size to the user visible portion */
|
||||
oldsize -= HEAP_ADMIN_SPACE;
|
||||
|
||||
/* If the new block is larger than the old one, copy the old
|
||||
** data only
|
||||
*/
|
||||
if (size > oldsize) {
|
||||
size = oldsize;
|
||||
}
|
||||
|
||||
/* Copy the block data */
|
||||
memcpy (newblock, block, size);
|
||||
free (block);
|
||||
}
|
||||
return newblock;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,213 @@
|
|||
;
|
||||
; Colin Leroy-Mira, 2024
|
||||
;
|
||||
; void* __fastcall__ realloc (void* block, register size_t size)
|
||||
;
|
||||
|
||||
.importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3, tmp4, sp
|
||||
.import _malloc, _memcpy, _free
|
||||
.import pushax, popptr1, return0
|
||||
.import incsp2, decsp2
|
||||
.export _realloc
|
||||
|
||||
.include "_heap.inc"
|
||||
|
||||
.macpack generic
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Aliases for clarity
|
||||
|
||||
block = ptr1
|
||||
size = ptr2
|
||||
ublock = ptr3
|
||||
oldsize = ptr4
|
||||
newblock = tmp1 ; (and tmp2)
|
||||
orgblock = tmp3 ; (and tmp4)
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Code
|
||||
|
||||
_realloc:
|
||||
sta size ; Store size
|
||||
stx size+1
|
||||
|
||||
jsr popptr1 ; Pop block
|
||||
|
||||
lda block+1 ; Is block null?
|
||||
tax
|
||||
ora block
|
||||
bne :+
|
||||
|
||||
lda size ; Block is null, just malloc
|
||||
ldx size+1
|
||||
jmp _malloc
|
||||
|
||||
: lda size ; Is size 0?
|
||||
ora size+1
|
||||
bne :+
|
||||
|
||||
lda block ; It is: free block (high byte already in X)
|
||||
jsr _free
|
||||
jmp return0
|
||||
|
||||
: clc ; Add internal used size
|
||||
lda size
|
||||
adc #HEAP_ADMIN_SPACE
|
||||
sta size
|
||||
bcc :+
|
||||
inc size+1
|
||||
bne :+
|
||||
|
||||
lda #$00 ; Size high byte now 0: We overflowed!
|
||||
tax
|
||||
rts
|
||||
|
||||
: ldx size+1 ; Should we round size up?
|
||||
bne :+
|
||||
cmp #.sizeof (freeblock)
|
||||
bcs :+
|
||||
|
||||
lda #.sizeof (freeblock)
|
||||
sta size ; (we presuppose that sizeof (freeblock) is < 256)
|
||||
|
||||
: lda block ; Get pointer to raw memory block
|
||||
sta orgblock ; Store original pointer
|
||||
sec
|
||||
sbc #.sizeof(usedblock)
|
||||
sta ublock
|
||||
lda block+1
|
||||
sta orgblock+1 ; Finish storing original pointer
|
||||
sbc #0
|
||||
sta ublock+1 ; We have our usedblock struct
|
||||
|
||||
; Get block start
|
||||
ldy #usedblock::start+1
|
||||
lda (ublock),y
|
||||
tax ; Backup ublock high
|
||||
dey
|
||||
lda (ublock),y
|
||||
|
||||
sta ublock ; Store ublock
|
||||
stx ublock+1
|
||||
|
||||
; Remember oldsize
|
||||
ldy #usedblock::size+1
|
||||
lda (ublock),y
|
||||
sta oldsize+1
|
||||
dey
|
||||
lda (ublock),y
|
||||
sta oldsize
|
||||
|
||||
clc ; Is the block at heap top?
|
||||
adc ublock
|
||||
tay
|
||||
lda ublock+1
|
||||
adc oldsize+1
|
||||
cmp ___heapptr+1
|
||||
bne must_malloc_new
|
||||
cpy ___heapptr
|
||||
bne must_malloc_new
|
||||
|
||||
tya ; Put ___heapptr back in A
|
||||
sec ; Check if we have enough memory at heap top
|
||||
sbc oldsize ; Substract oldsize
|
||||
sta newblock
|
||||
lda ___heapptr+1
|
||||
sbc oldsize+1
|
||||
sta newblock+1
|
||||
clc
|
||||
lda newblock ; And add size
|
||||
adc size
|
||||
sta newblock
|
||||
lda newblock+1
|
||||
adc size+1
|
||||
sta newblock+1
|
||||
bcs must_malloc_new ; If we have a carry there we overflowed
|
||||
|
||||
cmp ___heapend+1
|
||||
bne :+
|
||||
lda newblock
|
||||
cmp ___heapend
|
||||
: bcc :+
|
||||
bne must_malloc_new
|
||||
|
||||
: lda newblock ; There is enough space
|
||||
sta ___heapptr ; Update heapptr
|
||||
lda newblock+1
|
||||
sta ___heapptr+1
|
||||
|
||||
ldy #usedblock::start+1
|
||||
lda ublock+1
|
||||
sta (ublock),y ; Update block start
|
||||
dey
|
||||
lda ublock
|
||||
sta (ublock),y
|
||||
dey
|
||||
|
||||
.assert usedblock::size = usedblock::start-2, error
|
||||
lda size+1
|
||||
sta (ublock),y ; Update block size
|
||||
dey
|
||||
lda size
|
||||
sta (ublock),y
|
||||
|
||||
lda orgblock ; Return original block
|
||||
ldx orgblock+1
|
||||
rts
|
||||
|
||||
must_malloc_new: ; The block is not at heap top, or too big
|
||||
lda size+1
|
||||
pha ; Backup new size (at this point the only ptr
|
||||
tax ; we'll need after malloc). tmp* are safe
|
||||
lda size ; from malloc, memcpy and free.
|
||||
pha
|
||||
jsr _malloc
|
||||
|
||||
cmp #$00 ; Did malloc succeed?
|
||||
bne :+
|
||||
cpx #$00
|
||||
bne :+
|
||||
pla ; Pop size backup and return NULL
|
||||
pla
|
||||
txa ; X already 0
|
||||
rts ; No
|
||||
|
||||
: sta newblock ; Yes, store newblock
|
||||
stx newblock+1
|
||||
jsr pushax ; Push newblock for memcpy
|
||||
|
||||
lda orgblock ; Push orgblock for memcpy
|
||||
ldx orgblock+1
|
||||
jsr pushax
|
||||
|
||||
sec ; Remove admin space from oldsize
|
||||
lda oldsize
|
||||
sbc #<HEAP_ADMIN_SPACE
|
||||
sta oldsize
|
||||
lda oldsize+1
|
||||
sbc #>HEAP_ADMIN_SPACE
|
||||
sta oldsize+1
|
||||
|
||||
pla ; Restore new size to AX
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
tya
|
||||
|
||||
cmp oldsize ; Find the smallest size
|
||||
bcc :+
|
||||
cpx oldsize+1
|
||||
bcc :+
|
||||
|
||||
lda oldsize
|
||||
ldx oldsize+1
|
||||
|
||||
: jsr _memcpy ; And copy data
|
||||
|
||||
lda orgblock ; Free old block
|
||||
ldx orgblock+1
|
||||
jsr _free
|
||||
|
||||
lda newblock ; Return new block
|
||||
ldx newblock+1
|
||||
rts
|
|
@ -62,10 +62,6 @@
|
|||
; File is not open or the character is invalid
|
||||
|
||||
error: lda #EINVAL
|
||||
jsr ___seterrno
|
||||
lda #$FF ; Return -1
|
||||
tax
|
||||
rts
|
||||
jmp ___directerrno
|
||||
|
||||
.endproc
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
; void BitOtherClip (void *proc1, void* proc2, char skipl, char skipr, int skipy,
|
||||
; struct iconpic *myGfx);
|
||||
|
||||
; both proc1, proc2 should be: char __fastcall something (void);
|
||||
; both proc1, proc2 should be: char foo (void);
|
||||
; proc1 is called before reading a byte (.A returns next data)
|
||||
; proc2 is called before reading each byte which is not pattern (code >219)
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
;
|
||||
; Miloslaw Smyk, 2024
|
||||
;
|
||||
; CC65 runtime: Scale the primary register by 128, unsigned
|
||||
;
|
||||
|
||||
.export shlax7, aslax7
|
||||
|
||||
aslax7:
|
||||
shlax7: ; XXXXXXXL AAAAAAAl
|
||||
tay
|
||||
txa
|
||||
lsr ; XXXXXXXL -> 0XXXXXXX, L->C
|
||||
tya
|
||||
ror ; AAAAAAAl -> LAAAAAAA, l->C
|
||||
tax
|
||||
lda #$00 ; LAAAAAAA 00000000
|
||||
ror ; LAAAAAAA l0000000
|
||||
rts
|
||||
|
||||
; 10 bytes, 16 cycles + rts
|
|
@ -0,0 +1,18 @@
|
|||
;
|
||||
; Miloslaw Smyk, 2024
|
||||
;
|
||||
; CC65 runtime: Scale the primary register by 128, signed
|
||||
;
|
||||
|
||||
.export asrax7
|
||||
|
||||
asrax7: ; HXXXXXXL hAAAAAAl
|
||||
asl ; AAAAAAA0, h->C
|
||||
txa
|
||||
rol ; XXXXXXLh, H->C
|
||||
ldx #$00 ; 00000000 XXXXXXLh
|
||||
bcc :+
|
||||
dex ; 11111111 XXXXXXLh if C
|
||||
: rts
|
||||
|
||||
; 12 cycles max, 9 bytes
|
|
@ -0,0 +1,14 @@
|
|||
;
|
||||
; Colin Leroy-Mira, 2024
|
||||
;
|
||||
; CC65 runtime: Push ptr1 to stack.
|
||||
; A/X destroyed (set to ptr1)
|
||||
|
||||
.export pushptr1
|
||||
.import pushax
|
||||
.importzp ptr1
|
||||
|
||||
pushptr1:
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
jmp pushax
|
|
@ -0,0 +1,15 @@
|
|||
;
|
||||
; Ullrich von Bassewitz, 25.10.2000
|
||||
;
|
||||
; CC65 runtime: Return -1 in a/x
|
||||
;
|
||||
|
||||
.export returnFFFF
|
||||
|
||||
.proc returnFFFF
|
||||
|
||||
lda #$FF
|
||||
tax
|
||||
rts
|
||||
|
||||
.endproc
|
|
@ -0,0 +1,18 @@
|
|||
;
|
||||
; Miloslaw Smyk, 2024
|
||||
;
|
||||
; CC65 runtime: Scale the primary register by 128, unsigned
|
||||
;
|
||||
|
||||
.export shrax7
|
||||
|
||||
shrax7: ; HXXXXXXL hAAAAAAl
|
||||
asl ; AAAAAAA0, h->C
|
||||
txa
|
||||
rol ; XXXXXXLh, H->C
|
||||
ldx #$00 ; 00000000 XXXXXXLh
|
||||
bcc :+
|
||||
inx ; 0000000H XXXXXXLh if C
|
||||
: rts
|
||||
|
||||
; 12 cycles max, 9 bytes
|
|
@ -8,10 +8,15 @@
|
|||
;
|
||||
|
||||
.export exit, args, _open, _close, _read, _write
|
||||
.export __sysremove, ___osmaperrno
|
||||
|
||||
__sysremove := $FFF2
|
||||
___osmaperrno := $FFF3
|
||||
_open := $FFF4
|
||||
_close := $FFF5
|
||||
_read := $FFF6
|
||||
_write := $FFF7
|
||||
args := $FFF8
|
||||
exit := $FFF9
|
||||
|
||||
; $FFFA-FFFF are hardware vectors, extend before not after!
|
||||
|
|
|
@ -31,9 +31,12 @@ else
|
|||
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
endif
|
||||
|
||||
EXELIST_kim1 = \
|
||||
kimHello.bin \
|
||||
kimSieve.bin
|
||||
EXELIST_kim1 = \
|
||||
kimHello.bin \
|
||||
kimSieve.bin \
|
||||
kimLife.bin \
|
||||
kimTest.bin \
|
||||
kimGFX.bin
|
||||
|
||||
ifneq ($(EXELIST_$(SYS)),)
|
||||
samples: $(EXELIST_$(SYS))
|
||||
|
@ -50,13 +53,65 @@ else
|
|||
@echo > $(NULLDEV)
|
||||
endif
|
||||
|
||||
subs.o: subs.asm
|
||||
$(AS) subs.asm -o subs.o
|
||||
|
||||
ramfont.o: ramfont.asm
|
||||
$(AS) ramfont.asm -o ramfont.o
|
||||
|
||||
kimLife.bin: kimLife.c
|
||||
$(CL) -t kim1 -C kim1-60k.cfg -Oi -o kimLife.bin kimLife.c
|
||||
|
||||
kimTest.bin: kimTest.c
|
||||
$(CL) -t kim1 -C kim1-60k.cfg -Oi -o kimTest.bin kimTest.c
|
||||
|
||||
kimGFX.bin: kimGFX.c subs.o ramfont.o
|
||||
$(CL) -t kim1 --listing kimGFX.lst -C kim1-mtuE000.cfg -o kimGFX.bin kimGFX.c subs.o ramfont.o -Ln kimgfx.lbl
|
||||
|
||||
kimSieve.bin: kimSieve.c
|
||||
$(CL) -t kim1 -C kim1-60k.cfg -O -o kimSieve.bin kimSieve.c
|
||||
|
||||
kimHello.bin: kimHello.c
|
||||
$(CL) -t kim1 -O -o kimHello.bin kimHello.c
|
||||
|
||||
# To build an intel-format file for the CORSHAM SD card reader
|
||||
|
||||
kimLife.hex: kimLife.bin
|
||||
srec_cat kimLife.bin -binary -offset 0x2000 -o kimLife.hex -Intel -address-length=2
|
||||
|
||||
kimTest.hex: kimTest.bin
|
||||
srec_cat kimTest.bin -binary -offset 0x2000 -o kimTest.hex -Intel -address-length=2
|
||||
|
||||
kimGFX.hex: kimGFX.bin ramfont.o
|
||||
srec_cat kimGFX.bin -binary -offset 0x2000 -o kimGFX.hex -Intel -address-length=2
|
||||
|
||||
# To build a paper tape file for uploading to the KIM-1 via terminal
|
||||
|
||||
kimLife.ptp: kimLife.bin
|
||||
srec_cat kimLife.bin -binary -offset 0x2000 -o kimLife.ptp -MOS_Technologies
|
||||
|
||||
kimGFX.ptp: kimGFX.bin
|
||||
srec_cat kimGFX.bin -binary -offset 0x2000 -o kimGFX.ptp -MOS_Technologies
|
||||
|
||||
kimTest.ptp: kimTest.bin
|
||||
srec_cat kimTest.bin -binary -offset 0x2000 -o kimTest.ptp -MOS_Technologies
|
||||
|
||||
clean:
|
||||
@$(DEL) kimSieve.bin 2>$(NULLDEV)
|
||||
@$(DEL) kimHello.bin 2>$(NULLDEV)
|
||||
@$(DEL) kimLife.bin 2>$(NULLDEV)
|
||||
@$(DEL) kimLife.ptp 2>$(NULLDEV)
|
||||
@$(DEL) kimLife.hex 2>$(NULLDEV)
|
||||
@$(DEL) kimTest.bin 2>$(NULLDEV)
|
||||
@$(DEL) kimTest.ptp 2>$(NULLDEV)
|
||||
@$(DEL) kimTest.hex 2>$(NULLDEV)
|
||||
@$(DEL) kimGFX.bin 2>$(NULLDEV)
|
||||
@$(DEL) kimGFX.ptp 2>$(NULLDEV)
|
||||
@$(DEL) kimGFX.hex 2>$(NULLDEV)
|
||||
@$(DEL) kimgfx.lbl 2>$(NULLDEV)
|
||||
@$(DEL) kimGFX.lst 2>$(NULLDEV)
|
||||
@$(DEL) subs.o 2>$(NULLDEV)
|
||||
@$(DEL) ramfont.o 2>$(NULLDEV)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,290 @@
|
|||
// --------------------------------------------------------------------------
|
||||
// Simple Graphics Test for KIM-1 with MTU Visible Memory Board
|
||||
//
|
||||
// Assumes the MTU Visible Memory Board mapped at 0xA000 for 8K of video RAM
|
||||
//
|
||||
// davepl@davepl.com
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h> // For printf
|
||||
#include <stdlib.h> // For rand, srand
|
||||
#include <string.h> // For memcpy
|
||||
#include <ctype.h>
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
extern void ClearScreen(void); // In subs.asm
|
||||
extern void ScrollScreen(void);
|
||||
extern void DrawCircle(void);
|
||||
extern void SetPixel(void);
|
||||
extern void ClearPixel(void);
|
||||
extern void DrawChar(void);
|
||||
extern void Demo(void);
|
||||
extern void __fastcall__ Delay(byte loops);
|
||||
extern void __fastcall__ DrawLine(byte bSet);
|
||||
extern byte __fastcall__ AscToPet(byte in);
|
||||
extern byte __fastcall__ PetToAsc(byte in);
|
||||
extern byte __fastcall__ ReverseBits(byte in);
|
||||
extern void __fastcall__ CharOut(byte asci_char);
|
||||
extern byte __fastcall__ getch();
|
||||
extern unsigned char font8x8_basic[256][8];
|
||||
|
||||
extern int x1cord;
|
||||
extern int y1cord;
|
||||
extern int x2cord;
|
||||
extern int y2cord;
|
||||
extern int cursorX;
|
||||
extern int cursorY;
|
||||
|
||||
// If in zeropage:
|
||||
//
|
||||
// #pragma zpsym("x1cord")
|
||||
// #pragma zpsym("x2cord")
|
||||
// #pragma zpsym("y1cord")
|
||||
// #pragma zpsym("y2cord")
|
||||
|
||||
// Screen memory is placed at A000-BFFF, 320x200 pixels, mapped right to left within each horizontal byte
|
||||
|
||||
byte * screen = (byte *) 0xA000;
|
||||
|
||||
// Cursor position
|
||||
|
||||
#define SCREEN_WIDTH 320
|
||||
#define SCREEN_HEIGHT 200
|
||||
#define CHARWIDTH 8
|
||||
#define CHARHEIGHT 8
|
||||
#define BYTESPERROW (SCREEN_WIDTH / 8)
|
||||
#define BYTESPERCHARROW (BYTESPERROW * 8)
|
||||
#define CHARSPERROW (SCREEN_WIDTH / CHARWIDTH)
|
||||
#define ROWSPERCOLUMN (SCREEN_HEIGHT / CHARHEIGHT)
|
||||
|
||||
// SETPIXEL
|
||||
//
|
||||
// 0 <= x < 320
|
||||
// 0 <= y < 200
|
||||
//
|
||||
// Draws a pixel on the screen in white or black at pixel pos x, y
|
||||
|
||||
void SETPIXEL(int x, int y, byte b)
|
||||
{
|
||||
x1cord = x;
|
||||
y1cord = y;
|
||||
|
||||
if (b)
|
||||
SetPixel();
|
||||
else
|
||||
ClearPixel();
|
||||
}
|
||||
|
||||
// DRAWPIXEL
|
||||
//
|
||||
// 0 <= x < 320
|
||||
// 0 <= y < 200
|
||||
//
|
||||
// Turns on a screen pixel at pixel pos x,y
|
||||
|
||||
void DRAWPIXEL(int x, int y)
|
||||
{
|
||||
x1cord = x;
|
||||
y1cord = y;
|
||||
SetPixel();
|
||||
}
|
||||
|
||||
int c;
|
||||
|
||||
void DrawText(char * psz)
|
||||
{
|
||||
while (*psz)
|
||||
{
|
||||
while (cursorX >= CHARSPERROW)
|
||||
{
|
||||
cursorX -= CHARSPERROW;
|
||||
cursorY += 1;
|
||||
}
|
||||
|
||||
// If we've gone off the bottom of the screen, we scroll the screen and back up to the last line again
|
||||
|
||||
if (cursorY >= ROWSPERCOLUMN)
|
||||
{
|
||||
cursorY = ROWSPERCOLUMN - 1;
|
||||
ScrollScreen();
|
||||
}
|
||||
|
||||
// If we output a newline we advanced the cursor down one line and reset it to the left
|
||||
|
||||
if (*psz == 0x0A)
|
||||
{
|
||||
cursorX = 0;
|
||||
cursorY++;
|
||||
psz++;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = *psz;
|
||||
|
||||
__asm__ ("ldx %v", cursorX);
|
||||
__asm__ ("ldy %v", cursorY);
|
||||
__asm__ ("lda %v", c);
|
||||
DrawChar();
|
||||
cursorX++;
|
||||
psz++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawTextAt(int x, int y, char * psz)
|
||||
{
|
||||
cursorX = x;
|
||||
cursorY = y;
|
||||
DrawText(psz);
|
||||
}
|
||||
|
||||
// Something like Bresenham's algorithm for drawing a line
|
||||
/*
|
||||
void DrawLine(int x0, int y0, int x1, int y1, byte val)
|
||||
{
|
||||
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
|
||||
int dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
|
||||
int err = (dx > dy ? dx : -dy) / 2, e2;
|
||||
|
||||
while (1)
|
||||
{
|
||||
SETPIXEL(x0, y0, val);
|
||||
|
||||
if (x0 == x1 && y0 == y1)
|
||||
break;
|
||||
|
||||
e2 = err;
|
||||
|
||||
if (e2 > -dx)
|
||||
{
|
||||
err -= dy;
|
||||
x0 += sx;
|
||||
}
|
||||
if (e2 < dy)
|
||||
{
|
||||
err += dx;
|
||||
y0 += sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// DrawCircle
|
||||
//
|
||||
// Draw a circle without sin, cos, or floating point!
|
||||
|
||||
void DrawCircleC(int x0, int y0, int radius, byte)
|
||||
{
|
||||
x1cord = x0;
|
||||
y1cord = y0;
|
||||
y2cord = radius;
|
||||
DrawCircle();
|
||||
}
|
||||
|
||||
void DrawLineC(int x1, int y1, int x2, int y2, byte bSet)
|
||||
{
|
||||
x1cord = x1;
|
||||
y1cord = y1;
|
||||
x2cord = x2;
|
||||
y2cord = y2;
|
||||
DrawLine(bSet);
|
||||
}
|
||||
|
||||
// MirrorFont
|
||||
//
|
||||
// RAM font is backwards left-right relative to the way memory is laid out on the KIM-1, so we swap all the
|
||||
// bytes in place by reversing the order of the bits in every byte
|
||||
|
||||
void MirrorFont()
|
||||
{
|
||||
int c;
|
||||
byte * pb = (byte *) font8x8_basic;
|
||||
|
||||
for (c = 0; c < 128 * 8; c++)
|
||||
pb[c] = ReverseBits(pb[c]);
|
||||
}
|
||||
|
||||
// DrawScreenMoire
|
||||
//
|
||||
// Draws a moire pattern on the screen without clearing it first
|
||||
|
||||
void DrawMoire(int left, int top, int right, int bottom, byte pixel)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
for (x = left; x < right; x += 6)
|
||||
DrawLineC(x, top, right - x + left, bottom, pixel);
|
||||
|
||||
for (y = top; y < bottom; y += 6)
|
||||
DrawLineC(left, y, right, bottom - y + top, pixel);
|
||||
}
|
||||
|
||||
void DrawScreenMoire(int left, int top, int right, int bottom)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
DrawLineC(left, top, right, top, 1);
|
||||
DrawLineC(left, bottom, right, bottom, 1);
|
||||
DrawLineC(left, top, left, bottom, 1);
|
||||
DrawLineC(right, top, right, bottom, 1);
|
||||
|
||||
left++; top++; right--; bottom--;
|
||||
|
||||
for (x = left; x < right; x += 6)
|
||||
DrawLineC(x, top, right - x + left, bottom, 1);
|
||||
for (y = top; y < bottom; y += 6)
|
||||
DrawLineC(left, y, right, bottom - y + top, 1);
|
||||
for (x = left; x < right; x += 6)
|
||||
DrawLineC(x, top, right - x + left, bottom, 0);
|
||||
for (y = top; y < bottom; y += 6)
|
||||
DrawLineC(left, y, right, bottom - y + top, 0);
|
||||
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
|
||||
int i;
|
||||
int c = 0;
|
||||
|
||||
Demo();
|
||||
|
||||
CharOut('R');
|
||||
CharOut('E');
|
||||
CharOut('A');
|
||||
CharOut('D');
|
||||
CharOut('Y');
|
||||
CharOut('.');
|
||||
CharOut('\n');
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
c = toupper(getch());
|
||||
if (c != EOF)
|
||||
CharOut(c);
|
||||
}
|
||||
|
||||
// Clear the screen memory
|
||||
while(1)
|
||||
{
|
||||
Demo();
|
||||
DrawScreenMoire(0,30, 319, 199);
|
||||
Delay(10);
|
||||
|
||||
Demo();
|
||||
for (i = 5; i < 80; i+=5)
|
||||
{
|
||||
DrawCircleC(SCREEN_WIDTH/2, SCREEN_HEIGHT/2 + 20, i, 1);
|
||||
DrawCircleC(SCREEN_WIDTH/4, SCREEN_HEIGHT/2 + 20, i, 1);
|
||||
DrawCircleC(SCREEN_WIDTH*3/4, SCREEN_HEIGHT/2 + 20, i, 1);
|
||||
}
|
||||
|
||||
Delay(10);
|
||||
|
||||
}
|
||||
|
||||
printf("Done, exiting...\r\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
// --------------------------------------------------------------------------
|
||||
// Conway's Game of Life for KIM-1
|
||||
//
|
||||
// Assumes the MTU Visible Memory Board mapped at 0x8000 for 8K of video RAM
|
||||
//
|
||||
// Dave Plummer on a rainy Thursday
|
||||
//
|
||||
// davepl@davepl.com
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h> // For printf
|
||||
#include <stdlib.h> // For rand, srand
|
||||
#include <string.h> // For memcpy
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
// World size
|
||||
|
||||
#define WIDTH 320
|
||||
#define HEIGHT 200
|
||||
#define NUMBITS 64000
|
||||
#define NUMBYTES 8000
|
||||
#define DENSITY 50
|
||||
|
||||
// Screen memory is placed at 8000, our world copy at A000, and they use the same layout so
|
||||
// that we can memcpy from one to the other without translating
|
||||
|
||||
byte * world = (byte *) 0x8000;
|
||||
byte * new_world = (byte *) 0xA000;
|
||||
|
||||
// BITARRAY
|
||||
//
|
||||
// Access individual bits in a block of memory
|
||||
|
||||
// Access to the screen bitmap
|
||||
|
||||
byte GETBIT(byte *p, int n)
|
||||
{
|
||||
return (p[n >> 3] & (1 << (n & 7))) ? 1 : 0;
|
||||
}
|
||||
|
||||
void SETBIT(byte *p, int n)
|
||||
{
|
||||
p[n >> 3] |= (1 << (n & 7));
|
||||
}
|
||||
|
||||
void CLRBIT(byte *p, int n)
|
||||
{
|
||||
p[n >> 3] &= ~(1 << (n & 7));
|
||||
}
|
||||
|
||||
void SETPIXEL(byte * p, int x, int y, byte b)
|
||||
{
|
||||
if (b)
|
||||
SETBIT(p, y * WIDTH + x);
|
||||
else
|
||||
CLRBIT(p, y * WIDTH + x);
|
||||
}
|
||||
|
||||
byte GETPIXEL(byte *p, int x, int y)
|
||||
{
|
||||
return GETBIT(p, y * WIDTH + x);
|
||||
}
|
||||
|
||||
// RandomFillWorld
|
||||
//
|
||||
// Populates the initial world with random cells
|
||||
|
||||
void RandomFillWorld()
|
||||
{
|
||||
int x, y;
|
||||
|
||||
// I need a better way to see the RNG or it'll be the same game every time!
|
||||
srand(0);
|
||||
for (x = 0; x < WIDTH; x++)
|
||||
{
|
||||
for (y = 0; y < HEIGHT; y++)
|
||||
{
|
||||
byte b = ((rand() % 100) < DENSITY) ? 1 : 0;
|
||||
SETPIXEL(world, x, y, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CountNeighbors
|
||||
//
|
||||
// Count the number of live cells around the given spot, excluding the actual spot specified
|
||||
|
||||
int CountNeighbors(int x, int y)
|
||||
{
|
||||
int i, j, nx, ny, count = 0;
|
||||
|
||||
for (j = -1; j <= 1; j++)
|
||||
{
|
||||
for (i = -1; i <= 1; i++)
|
||||
{
|
||||
if (i != 0 || j != 0)
|
||||
{
|
||||
nx = (x + i + WIDTH) % WIDTH;
|
||||
ny = (y + j + HEIGHT) % HEIGHT;
|
||||
count += GETPIXEL(world, nx, ny) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// UpdateWorld
|
||||
//
|
||||
// Applies the rules of Conway's Game of Life to the cells
|
||||
|
||||
void UpdateWorld()
|
||||
{
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < HEIGHT; y++)
|
||||
{
|
||||
for (x = 0; x < WIDTH; x++)
|
||||
{
|
||||
int neighbors = CountNeighbors(x, y);
|
||||
if (GETPIXEL(world, x, y))
|
||||
SETPIXEL(new_world, x, y, (neighbors == 2 || neighbors == 3));
|
||||
else
|
||||
SETPIXEL(new_world, x, y, (neighbors == 3));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
printf("\r\nStarting Conway's Game of Life: Randomizing World...\r\n");
|
||||
RandomFillWorld();
|
||||
printf("World Ready, Running!\r\n");
|
||||
|
||||
for (;;)
|
||||
{
|
||||
UpdateWorld();
|
||||
printf("[");
|
||||
memcpy(world, new_world, NUMBYTES);
|
||||
printf("]");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,262 @@
|
|||
// --------------------------------------------------------------------------
|
||||
// Diagnostics Test for KIM-1
|
||||
//
|
||||
// Dave Plummer
|
||||
// davepl@davepl.com
|
||||
//
|
||||
// Memory test examples by Michael Barr
|
||||
//
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h> // For printf
|
||||
#include <stdlib.h> // For rand, srand
|
||||
#include <string.h> // For memcpy
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
// RepeatChar
|
||||
//
|
||||
// Outputs a given character N times
|
||||
|
||||
void RepeatChar(char c, size_t count)
|
||||
{
|
||||
while (count--)
|
||||
putc(c, stdout);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Function: memTestDataBus()
|
||||
*
|
||||
* Description: Test the data bus wiring in a memory region by
|
||||
* performing a walking 1's test at a fixed address
|
||||
* within that region. The address (and hence the
|
||||
* memory region) is selected by the caller.
|
||||
*
|
||||
* Returns: 0 if the test succeeds.
|
||||
* A non-zero result is the first pattern that failed.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
byte memTestDataBus(volatile byte * address)
|
||||
{
|
||||
byte pattern;
|
||||
|
||||
// Perform a walking 1's test at the given address.
|
||||
|
||||
for (pattern = 1; pattern != 0; pattern <<= 1)
|
||||
{
|
||||
// Write the test pattern.
|
||||
*address = pattern;
|
||||
|
||||
// Read it back and check it
|
||||
if (*address != pattern)
|
||||
{
|
||||
printf("\r\nmemTestDataBus: FAILED at %04x with pattern %02x\r\n", address, pattern);
|
||||
return (pattern);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Function: memTestAddressBus()
|
||||
*
|
||||
* Description: Test the address bus wiring in a memory region by
|
||||
* performing a walking 1's test on the relevant bits
|
||||
* of the address and checking for aliasing. This test
|
||||
* will find single-bit address failures such as stuck
|
||||
* -high, stuck-low, and shorted pins. The base address
|
||||
* and size of the region are selected by the caller.
|
||||
*
|
||||
* Notes: For best results, the selected base address should
|
||||
* have enough LSB 0's to guarantee single address bit
|
||||
* changes. For example, to test a 64-Kbyte region,
|
||||
* select a base address on a 64-Kbyte boundary. Also,
|
||||
* select the region size as a power-of-two--if at all
|
||||
* possible.
|
||||
*
|
||||
* Returns: NULL if the test succeeds.
|
||||
* A non-zero result is the first address at which an
|
||||
* aliasing problem was uncovered. By examining the
|
||||
* contents of memory, it may be possible to gather
|
||||
* additional information about the problem.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
byte * memTestAddressBus(volatile byte * baseAddress, unsigned long nBytes)
|
||||
{
|
||||
unsigned long addressMask = (nBytes/sizeof(byte) - 1);
|
||||
unsigned long offset;
|
||||
unsigned long testOffset;
|
||||
|
||||
byte pattern = (byte) 0xAAAAAAAA;
|
||||
byte antipattern = (byte) 0x55555555;
|
||||
|
||||
|
||||
//Write the default pattern at each of the power-of-two offsets.
|
||||
|
||||
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
|
||||
{
|
||||
baseAddress[offset] = pattern;
|
||||
}
|
||||
|
||||
// Check for address bits stuck high.
|
||||
|
||||
testOffset = 0;
|
||||
baseAddress[testOffset] = antipattern;
|
||||
|
||||
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
|
||||
{
|
||||
if (baseAddress[offset] != pattern)
|
||||
{
|
||||
printf("\r\nmemTestAddressBus: FAILED at %04x with pattern %02x\r\n", baseAddress+offset, pattern);
|
||||
return ((byte *) &baseAddress[offset]);
|
||||
}
|
||||
if (offset % 1024 == 0)
|
||||
printf(".");
|
||||
}
|
||||
|
||||
baseAddress[testOffset] = pattern;
|
||||
|
||||
|
||||
// Check for address bits stuck low or shorted.
|
||||
|
||||
for (testOffset = 1; (testOffset & addressMask) != 0; testOffset <<= 1)
|
||||
{
|
||||
baseAddress[testOffset] = antipattern;
|
||||
|
||||
if (baseAddress[0] != pattern)
|
||||
{
|
||||
return ((byte *) &baseAddress[testOffset]);
|
||||
}
|
||||
|
||||
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
|
||||
{
|
||||
if ((baseAddress[offset] != pattern) && (offset != testOffset))
|
||||
{
|
||||
printf("\r\nmemTestAddressBus: FAILED at %04x with pattern %02x\r\n", baseAddress+offset, pattern);
|
||||
return ((byte *) &baseAddress[testOffset]);
|
||||
}
|
||||
}
|
||||
baseAddress[testOffset] = pattern;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Function: memTestDevice()
|
||||
*
|
||||
* Description: Test the integrity of a physical memory device by
|
||||
* performing an increment/decrement test over the
|
||||
* entire region. In the process every storage bit
|
||||
* in the device is tested as a zero and a one. The
|
||||
* base address and the size of the region are
|
||||
* selected by the caller.
|
||||
*
|
||||
* Returns: NULL if the test succeeds.
|
||||
*
|
||||
* A non-zero result is the first address at which an
|
||||
* incorrect value was read back. By examining the
|
||||
* contents of memory, it may be possible to gather
|
||||
* additional information about the problem.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
byte * memTestDevice(volatile byte * baseAddress, unsigned long nBytes)
|
||||
{
|
||||
unsigned long offset;
|
||||
unsigned long nWords = nBytes / sizeof(byte);
|
||||
|
||||
byte pattern;
|
||||
byte antipattern;
|
||||
|
||||
|
||||
// Fill memory with a known pattern.
|
||||
|
||||
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
|
||||
baseAddress[offset] = pattern;
|
||||
|
||||
// Check each location and invert it for the second pass.
|
||||
|
||||
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
|
||||
{
|
||||
if (offset % 1024 == 0)
|
||||
printf("%04X ", (int) &baseAddress[offset]);
|
||||
|
||||
if (baseAddress[offset] != pattern)
|
||||
{
|
||||
printf("\r\nmemTestDevice: FAILED at %04x with pattern %02x\r\n", (int) &baseAddress[offset], pattern);
|
||||
return ((byte *) &baseAddress[offset]);
|
||||
}
|
||||
|
||||
antipattern = ~pattern;
|
||||
baseAddress[offset] = antipattern;
|
||||
|
||||
}
|
||||
|
||||
// Check each location for the inverted pattern and zero it.
|
||||
|
||||
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
|
||||
{
|
||||
if (offset % 1024 == 0)
|
||||
printf("%04X ", (int) &baseAddress[offset]);
|
||||
|
||||
antipattern = ~pattern;
|
||||
if (baseAddress[offset] != antipattern)
|
||||
{
|
||||
printf("\r\nmemTestDevice: FAILED at %04x with antipattern %02x\r\n", (int) &baseAddress[offset], pattern);
|
||||
return ((byte *) &baseAddress[offset]);
|
||||
}
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// TestMemory
|
||||
//
|
||||
// Run all three memory tests
|
||||
|
||||
byte TestMemory(byte * startAddress, unsigned long size)
|
||||
{
|
||||
if ((memTestDataBus(startAddress) != 0) ||
|
||||
(memTestAddressBus(startAddress, size) != NULL) ||
|
||||
(memTestDevice(startAddress, size) != NULL))
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
printf("\r\nTesting KIM-1...\r\n");
|
||||
RepeatChar('-', 39);
|
||||
|
||||
printf("\r\nTesting RIOT RAM: 1780-17BF\r\n");
|
||||
if (TestMemory((byte *)0x1780, 0x17BF - 0x1780))
|
||||
return 0;
|
||||
|
||||
printf("\r\nTesting RIOT RAM: 17C0-17E6\r\n");
|
||||
if (TestMemory((byte *)0x17C0, 0x17E6 - 0x17C0))
|
||||
return 0;
|
||||
|
||||
printf("\r\nTesting Memory: 0400-13FF\r\n");
|
||||
if (TestMemory((byte *)0x0400, 0x13FF - 0x0400))
|
||||
return 0;
|
||||
|
||||
printf("\r\nTesting Memory: 4000-DFFF\r\n");
|
||||
if (TestMemory((byte *)0x4000, 0xDFFF - 0x4000))
|
||||
return 0;
|
||||
|
||||
printf("\r\nPASS!\r\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,272 @@
|
|||
;-----------------------------------------------------------------------------------
|
||||
; KIMGFX: Simple pixel graphics for the MOS/Commodore KIM-1
|
||||
;-----------------------------------------------------------------------------------
|
||||
; (c) Plummer's Software Ltd, 04/25/2023 Created
|
||||
; David Plummer
|
||||
;-----------------------------------------------------------------------------------
|
||||
;
|
||||
; File: ramfont.s
|
||||
; Magnetic OCR (check number style) Font data
|
||||
;
|
||||
;-----------------------------------------------------------------------------------
|
||||
|
||||
.segment "CODE"
|
||||
.export _font8x8_basic
|
||||
|
||||
_font8x8_basic:
|
||||
.byte $1c, $22, $4a, $56, $4c, $20, $1e, $00 ; PETSCII code 0
|
||||
.byte $3c, $24, $24, $7e, $62, $62, $62, $00 ; PETSCII code 1
|
||||
.byte $78, $44, $44, $7c, $62, $62, $7e, $00 ; PETSCII code 2
|
||||
.byte $7e, $42, $40, $60, $60, $62, $7e, $00 ; PETSCII code 3
|
||||
.byte $7c, $46, $42, $62, $62, $66, $7c, $00 ; PETSCII code 4
|
||||
.byte $7e, $40, $40, $7c, $60, $60, $7e, $00 ; PETSCII code 5
|
||||
.byte $7e, $40, $40, $7e, $60, $60, $60, $00 ; PETSCII code 6
|
||||
.byte $7e, $42, $40, $6e, $62, $62, $7e, $00 ; PETSCII code 7
|
||||
.byte $42, $42, $42, $7e, $62, $62, $62, $00 ; PETSCII code 8
|
||||
.byte $08, $08, $08, $0c, $0c, $0c, $0c, $00 ; PETSCII code 9
|
||||
.byte $04, $04, $04, $06, $06, $46, $7e, $00 ; PETSCII code 10
|
||||
.byte $42, $44, $48, $7c, $62, $62, $62, $00 ; PETSCII code 11
|
||||
.byte $40, $40, $40, $60, $60, $60, $7e, $00 ; PETSCII code 12
|
||||
.byte $7e, $4a, $4a, $6a, $6a, $6a, $6a, $00 ; PETSCII code 13
|
||||
.byte $7e, $42, $42, $62, $62, $62, $62, $00 ; PETSCII code 14
|
||||
.byte $7e, $46, $42, $42, $42, $42, $7e, $00 ; PETSCII code 15
|
||||
.byte $7e, $42, $42, $7e, $60, $60, $60, $00 ; PETSCII code 16
|
||||
.byte $7e, $42, $42, $42, $4a, $4e, $7e, $00 ; PETSCII code 17
|
||||
.byte $7c, $44, $44, $7c, $62, $62, $62, $00 ; PETSCII code 18
|
||||
.byte $7e, $42, $40, $7e, $06, $46, $7e, $00 ; PETSCII code 19
|
||||
.byte $3e, $10, $10, $18, $18, $18, $18, $00 ; PETSCII code 20
|
||||
.byte $42, $42, $42, $62, $62, $62, $7e, $00 ; PETSCII code 21
|
||||
.byte $62, $62, $62, $66, $24, $24, $3c, $00 ; PETSCII code 22
|
||||
.byte $4a, $4a, $4a, $6a, $6a, $6a, $7e, $00 ; PETSCII code 23
|
||||
.byte $42, $42, $66, $18, $66, $62, $62, $00 ; PETSCII code 24
|
||||
.byte $22, $22, $22, $3e, $18, $18, $18, $00 ; PETSCII code 25
|
||||
.byte $7e, $42, $06, $18, $60, $62, $7e, $00 ; PETSCII code 26
|
||||
.byte $3c, $20, $20, $20, $20, $20, $3c, $00 ; PETSCII code 27
|
||||
.byte $00, $40, $20, $10, $08, $04, $02, $00 ; PETSCII code 28
|
||||
.byte $3c, $04, $04, $04, $04, $04, $3c, $00 ; PETSCII code 29
|
||||
.byte $00, $08, $1c, $2a, $08, $08, $14, $14 ; PETSCII code 30
|
||||
.byte $00, $00, $10, $20, $7f, $20, $10, $00 ; PETSCII code 31
|
||||
.byte $00, $00, $00, $00, $00, $00, $00, $00 ; PETSCII code 32
|
||||
.byte $08, $08, $08, $0c, $0c, $00, $0c, $00 ; PETSCII code 33
|
||||
.byte $6c, $24, $6c, $00, $00, $00, $00, $00 ; PETSCII code 34
|
||||
.byte $24, $24, $7e, $24, $7e, $24, $24, $00 ; PETSCII code 35
|
||||
.byte $08, $3e, $20, $3e, $06, $3e, $08, $00 ; PETSCII code 36
|
||||
.byte $00, $62, $64, $08, $10, $26, $46, $00 ; PETSCII code 37
|
||||
.byte $3c, $20, $24, $7e, $64, $64, $7c, $00 ; PETSCII code 38
|
||||
.byte $1c, $18, $10, $00, $00, $00, $00, $00 ; PETSCII code 39
|
||||
.byte $04, $08, $10, $10, $10, $08, $04, $00 ; PETSCII code 40
|
||||
.byte $20, $10, $08, $08, $08, $10, $20, $00 ; PETSCII code 41
|
||||
.byte $08, $2a, $1c, $3e, $1c, $2a, $08, $00 ; PETSCII code 42
|
||||
.byte $00, $08, $08, $3e, $08, $08, $00, $00 ; PETSCII code 43
|
||||
.byte $00, $00, $00, $00, $00, $18, $18, $08 ; PETSCII code 44
|
||||
.byte $00, $00, $00, $7e, $00, $00, $00, $00 ; PETSCII code 45
|
||||
.byte $00, $00, $00, $00, $00, $18, $18, $00 ; PETSCII code 46
|
||||
.byte $00, $02, $04, $08, $10, $20, $40, $00 ; PETSCII code 47
|
||||
.byte $7e, $62, $52, $4a, $46, $46, $7e, $00 ; PETSCII code 48
|
||||
.byte $18, $08, $08, $18, $18, $1a, $3e, $00 ; PETSCII code 49
|
||||
.byte $7e, $42, $02, $7e, $60, $60, $7e, $00 ; PETSCII code 50
|
||||
.byte $7c, $44, $04, $1e, $06, $46, $7e, $00 ; PETSCII code 51
|
||||
.byte $44, $44, $44, $44, $7e, $0c, $0c, $00 ; PETSCII code 52
|
||||
.byte $7e, $40, $7e, $06, $06, $46, $7e, $00 ; PETSCII code 53
|
||||
.byte $7e, $42, $40, $7e, $46, $46, $7e, $00 ; PETSCII code 54
|
||||
.byte $7e, $02, $02, $06, $06, $06, $06, $00 ; PETSCII code 55
|
||||
.byte $3c, $24, $24, $7e, $46, $46, $7e, $00 ; PETSCII code 56
|
||||
.byte $7e, $42, $42, $7e, $06, $06, $06, $00 ; PETSCII code 57
|
||||
.byte $00, $00, $18, $00, $00, $18, $00, $00 ; PETSCII code 58
|
||||
.byte $00, $00, $18, $00, $00, $18, $18, $08 ; PETSCII code 59
|
||||
.byte $0e, $18, $30, $60, $30, $18, $0e, $00 ; PETSCII code 60
|
||||
.byte $00, $00, $7e, $00, $7e, $00, $00, $00 ; PETSCII code 61
|
||||
.byte $70, $18, $0c, $06, $0c, $18, $70, $00 ; PETSCII code 62
|
||||
.byte $7e, $02, $02, $7e, $60, $00, $60, $00 ; PETSCII code 63
|
||||
.byte $00, $00, $00, $00, $ff, $00, $00, $00 ; PETSCII code 64
|
||||
.byte $08, $1c, $3e, $7f, $7f, $1c, $3e, $00 ; PETSCII code 65
|
||||
.byte $10, $10, $10, $10, $10, $10, $10, $10 ; PETSCII code 66
|
||||
.byte $00, $00, $00, $ff, $00, $00, $00, $00 ; PETSCII code 67
|
||||
.byte $00, $00, $ff, $00, $00, $00, $00, $00 ; PETSCII code 68
|
||||
.byte $00, $ff, $00, $00, $00, $00, $00, $00 ; PETSCII code 69
|
||||
.byte $00, $00, $00, $00, $00, $ff, $00, $00 ; PETSCII code 70
|
||||
.byte $20, $20, $20, $20, $20, $20, $20, $20 ; PETSCII code 71
|
||||
.byte $04, $04, $04, $04, $04, $04, $04, $04 ; PETSCII code 72
|
||||
.byte $00, $00, $00, $00, $e0, $10, $08, $08 ; PETSCII code 73
|
||||
.byte $08, $08, $08, $04, $03, $00, $00, $00 ; PETSCII code 74
|
||||
.byte $08, $08, $08, $10, $e0, $00, $00, $00 ; PETSCII code 75
|
||||
.byte $80, $80, $80, $80, $80, $80, $80, $ff ; PETSCII code 76
|
||||
.byte $80, $40, $20, $10, $08, $04, $02, $01 ; PETSCII code 77
|
||||
.byte $01, $02, $04, $08, $10, $20, $40, $80 ; PETSCII code 78
|
||||
.byte $ff, $80, $80, $80, $80, $80, $80, $80 ; PETSCII code 79
|
||||
.byte $ff, $01, $01, $01, $01, $01, $01, $01 ; PETSCII code 80
|
||||
.byte $00, $3c, $7e, $7e, $7e, $7e, $3c, $00 ; PETSCII code 81
|
||||
.byte $00, $00, $00, $00, $00, $00, $ff, $00 ; PETSCII code 82
|
||||
.byte $36, $7f, $7f, $7f, $3e, $1c, $08, $00 ; PETSCII code 83
|
||||
.byte $40, $40, $40, $40, $40, $40, $40, $40 ; PETSCII code 84
|
||||
.byte $00, $00, $00, $00, $03, $04, $08, $08 ; PETSCII code 85
|
||||
.byte $81, $42, $24, $18, $18, $24, $42, $81 ; PETSCII code 86
|
||||
.byte $00, $3c, $42, $42, $42, $42, $3c, $00 ; PETSCII code 87
|
||||
.byte $08, $1c, $2a, $77, $2a, $08, $08, $00 ; PETSCII code 88
|
||||
.byte $02, $02, $02, $02, $02, $02, $02, $02 ; PETSCII code 89
|
||||
.byte $08, $1c, $3e, $7f, $3e, $1c, $08, $00 ; PETSCII code 90
|
||||
.byte $08, $08, $08, $08, $ff, $08, $08, $08 ; PETSCII code 91
|
||||
.byte $a0, $50, $a0, $50, $a0, $50, $a0, $50 ; PETSCII code 92
|
||||
.byte $08, $08, $08, $08, $08, $08, $08, $08 ; PETSCII code 93
|
||||
.byte $00, $00, $01, $3e, $54, $14, $14, $00 ; PETSCII code 94
|
||||
.byte $ff, $7f, $3f, $1f, $0f, $07, $03, $01 ; PETSCII code 95
|
||||
.byte $00, $00, $00, $00, $00, $00, $00, $00 ; PETSCII code 96
|
||||
.byte $f0, $f0, $f0, $f0, $f0, $f0, $f0, $f0 ; PETSCII code 97
|
||||
.byte $00, $00, $00, $00, $ff, $ff, $ff, $ff ; PETSCII code 98
|
||||
.byte $ff, $00, $00, $00, $00, $00, $00, $00 ; PETSCII code 99
|
||||
.byte $00, $00, $00, $00, $00, $00, $00, $ff ; PETSCII code 100
|
||||
.byte $80, $80, $80, $80, $80, $80, $80, $80 ; PETSCII code 101
|
||||
.byte $aa, $55, $aa, $55, $aa, $55, $aa, $55 ; PETSCII code 102
|
||||
.byte $01, $01, $01, $01, $01, $01, $01, $01 ; PETSCII code 103
|
||||
.byte $00, $00, $00, $00, $aa, $55, $aa, $55 ; PETSCII code 104
|
||||
.byte $ff, $fe, $fc, $f8, $f0, $e0, $c0, $80 ; PETSCII code 105
|
||||
.byte $03, $03, $03, $03, $03, $03, $03, $03 ; PETSCII code 106
|
||||
.byte $08, $08, $08, $08, $0f, $08, $08, $08 ; PETSCII code 107
|
||||
.byte $00, $00, $00, $00, $0f, $0f, $0f, $0f ; PETSCII code 108
|
||||
.byte $08, $08, $08, $08, $0f, $00, $00, $00 ; PETSCII code 109
|
||||
.byte $00, $00, $00, $00, $f8, $08, $08, $08 ; PETSCII code 110
|
||||
.byte $00, $00, $00, $00, $00, $00, $ff, $ff ; PETSCII code 111
|
||||
.byte $00, $00, $00, $00, $0f, $08, $08, $08 ; PETSCII code 112
|
||||
.byte $08, $08, $08, $08, $ff, $00, $00, $00 ; PETSCII code 113
|
||||
.byte $00, $00, $00, $00, $ff, $08, $08, $08 ; PETSCII code 114
|
||||
.byte $08, $08, $08, $08, $f8, $08, $08, $08 ; PETSCII code 115
|
||||
.byte $c0, $c0, $c0, $c0, $c0, $c0, $c0, $c0 ; PETSCII code 116
|
||||
.byte $e0, $e0, $e0, $e0, $e0, $e0, $e0, $e0 ; PETSCII code 117
|
||||
.byte $07, $07, $07, $07, $07, $07, $07, $07 ; PETSCII code 118
|
||||
.byte $ff, $ff, $00, $00, $00, $00, $00, $00 ; PETSCII code 119
|
||||
.byte $ff, $ff, $ff, $00, $00, $00, $00, $00 ; PETSCII code 120
|
||||
.byte $00, $00, $00, $00, $00, $ff, $ff, $ff ; PETSCII code 121
|
||||
.byte $01, $01, $01, $01, $01, $01, $01, $ff ; PETSCII code 122
|
||||
.byte $00, $00, $00, $00, $f0, $f0, $f0, $f0 ; PETSCII code 123
|
||||
.byte $0f, $0f, $0f, $0f, $00, $00, $00, $00 ; PETSCII code 124
|
||||
.byte $08, $08, $08, $08, $f8, $00, $00, $00 ; PETSCII code 125
|
||||
.byte $f0, $f0, $f0, $f0, $00, $00, $00, $00 ; PETSCII code 126
|
||||
.byte $f0, $f0, $f0, $f0, $0f, $0f, $0f, $0f ; PETSCII code 127
|
||||
.byte $1c, $22, $4a, $56, $4c, $20, $1e, $00 ; PETSCII code 128
|
||||
.byte $00, $00, $3c, $04, $7c, $64, $7c, $00 ; PETSCII code 129
|
||||
.byte $40, $40, $7e, $42, $62, $62, $7e, $00 ; PETSCII code 130
|
||||
.byte $00, $00, $7e, $42, $60, $62, $7e, $00 ; PETSCII code 131
|
||||
.byte $02, $02, $7e, $42, $62, $62, $7e, $00 ; PETSCII code 132
|
||||
.byte $00, $00, $7e, $42, $7e, $60, $7e, $00 ; PETSCII code 133
|
||||
.byte $1e, $12, $10, $7c, $18, $18, $18, $00 ; PETSCII code 134
|
||||
.byte $00, $00, $7e, $42, $62, $7e, $02, $7e ; PETSCII code 135
|
||||
.byte $40, $40, $7e, $42, $62, $62, $62, $00 ; PETSCII code 136
|
||||
.byte $18, $00, $10, $10, $18, $18, $18, $00 ; PETSCII code 137
|
||||
.byte $0c, $00, $08, $0c, $0c, $0c, $44, $7c ; PETSCII code 138
|
||||
.byte $40, $40, $44, $48, $78, $64, $64, $00 ; PETSCII code 139
|
||||
.byte $10, $10, $10, $10, $18, $18, $18, $00 ; PETSCII code 140
|
||||
.byte $00, $00, $7f, $49, $6d, $6d, $6d, $00 ; PETSCII code 141
|
||||
.byte $00, $00, $7e, $42, $62, $62, $62, $00 ; PETSCII code 142
|
||||
.byte $00, $00, $7e, $42, $62, $62, $7e, $00 ; PETSCII code 143
|
||||
.byte $00, $00, $7e, $42, $62, $7e, $40, $40 ; PETSCII code 144
|
||||
.byte $00, $00, $7e, $42, $46, $7e, $02, $02 ; PETSCII code 145
|
||||
.byte $00, $00, $7e, $40, $60, $60, $60, $00 ; PETSCII code 146
|
||||
.byte $00, $00, $7e, $40, $7e, $06, $7e, $00 ; PETSCII code 147
|
||||
.byte $10, $10, $7c, $10, $18, $18, $18, $00 ; PETSCII code 148
|
||||
.byte $00, $00, $42, $42, $62, $62, $7e, $00 ; PETSCII code 149
|
||||
.byte $00, $00, $62, $62, $66, $24, $3c, $00 ; PETSCII code 150
|
||||
.byte $00, $00, $49, $49, $6d, $6d, $7f, $00 ; PETSCII code 151
|
||||
.byte $00, $00, $42, $42, $3c, $62, $62, $00 ; PETSCII code 152
|
||||
.byte $00, $00, $62, $62, $42, $7e, $02, $7e ; PETSCII code 153
|
||||
.byte $00, $00, $7e, $06, $18, $60, $7e, $00 ; PETSCII code 154
|
||||
.byte $3c, $20, $20, $20, $20, $20, $3c, $00 ; PETSCII code 155
|
||||
.byte $00, $40, $20, $10, $08, $04, $02, $00 ; PETSCII code 156
|
||||
.byte $3c, $04, $04, $04, $04, $04, $3c, $00 ; PETSCII code 157
|
||||
.byte $00, $08, $1c, $2a, $08, $08, $14, $14 ; PETSCII code 158
|
||||
.byte $00, $00, $10, $20, $7f, $20, $10, $00 ; PETSCII code 159
|
||||
.byte $00, $00, $00, $00, $00, $00, $00, $00 ; PETSCII code 160
|
||||
.byte $08, $08, $08, $0c, $0c, $00, $0c, $00 ; PETSCII code 161
|
||||
.byte $6c, $24, $6c, $00, $00, $00, $00, $00 ; PETSCII code 162
|
||||
.byte $24, $24, $7e, $24, $7e, $24, $24, $00 ; PETSCII code 163
|
||||
.byte $08, $3e, $20, $3e, $06, $3e, $08, $00 ; PETSCII code 164
|
||||
.byte $00, $62, $64, $08, $10, $26, $46, $00 ; PETSCII code 165
|
||||
.byte $3c, $20, $24, $7e, $64, $64, $7c, $00 ; PETSCII code 166
|
||||
.byte $1c, $18, $10, $00, $00, $00, $00, $00 ; PETSCII code 167
|
||||
.byte $04, $08, $10, $10, $10, $08, $04, $00 ; PETSCII code 168
|
||||
.byte $20, $10, $08, $08, $08, $10, $20, $00 ; PETSCII code 169
|
||||
.byte $08, $2a, $1c, $3e, $1c, $2a, $08, $00 ; PETSCII code 170
|
||||
.byte $00, $08, $08, $3e, $08, $08, $00, $00 ; PETSCII code 171
|
||||
.byte $00, $00, $00, $00, $00, $18, $18, $08 ; PETSCII code 172
|
||||
.byte $00, $00, $00, $7e, $00, $00, $00, $00 ; PETSCII code 173
|
||||
.byte $00, $00, $00, $00, $00, $18, $18, $00 ; PETSCII code 174
|
||||
.byte $00, $02, $04, $08, $10, $20, $40, $00 ; PETSCII code 175
|
||||
.byte $7e, $62, $52, $4a, $46, $46, $7e, $00 ; PETSCII code 176
|
||||
.byte $38, $08, $08, $18, $18, $1a, $3e, $00 ; PETSCII code 177
|
||||
.byte $7e, $42, $02, $7e, $60, $60, $7e, $00 ; PETSCII code 178
|
||||
.byte $7c, $44, $04, $1e, $06, $46, $7e, $00 ; PETSCII code 179
|
||||
.byte $44, $44, $44, $44, $7e, $0c, $0c, $00 ; PETSCII code 180
|
||||
.byte $7e, $40, $7e, $06, $06, $46, $7e, $00 ; PETSCII code 181
|
||||
.byte $7e, $42, $40, $7e, $46, $46, $7e, $00 ; PETSCII code 182
|
||||
.byte $7e, $02, $02, $06, $06, $06, $06, $00 ; PETSCII code 183
|
||||
.byte $3c, $24, $24, $7e, $46, $46, $7e, $00 ; PETSCII code 184
|
||||
.byte $7e, $42, $42, $7e, $06, $06, $06, $00 ; PETSCII code 185
|
||||
.byte $00, $00, $18, $00, $00, $18, $00, $00 ; PETSCII code 186
|
||||
.byte $00, $00, $18, $00, $00, $18, $18, $08 ; PETSCII code 187
|
||||
.byte $0e, $18, $30, $60, $30, $18, $0e, $00 ; PETSCII code 188
|
||||
.byte $00, $00, $7e, $00, $7e, $00, $00, $00 ; PETSCII code 189
|
||||
.byte $70, $18, $0c, $06, $0c, $18, $70, $00 ; PETSCII code 190
|
||||
.byte $7e, $02, $02, $7e, $60, $00, $60, $00 ; PETSCII code 191
|
||||
.byte $00, $00, $00, $00, $ff, $00, $00, $00 ; PETSCII code 192
|
||||
.byte $3c, $24, $24, $7e, $62, $62, $62, $00 ; PETSCII code 193
|
||||
.byte $78, $44, $44, $7c, $62, $62, $7e, $00 ; PETSCII code 194
|
||||
.byte $7e, $42, $40, $60, $60, $62, $7e, $00 ; PETSCII code 195
|
||||
.byte $7c, $46, $42, $62, $62, $66, $7c, $00 ; PETSCII code 196
|
||||
.byte $7e, $40, $40, $78, $60, $60, $7e, $00 ; PETSCII code 197
|
||||
.byte $7e, $40, $40, $7e, $60, $60, $60, $00 ; PETSCII code 198
|
||||
.byte $7e, $42, $40, $6e, $62, $62, $7e, $00 ; PETSCII code 199
|
||||
.byte $42, $42, $42, $7e, $62, $62, $62, $00 ; PETSCII code 200
|
||||
.byte $08, $08, $08, $0c, $0c, $0c, $0c, $00 ; PETSCII code 201
|
||||
.byte $04, $04, $04, $06, $06, $46, $7e, $00 ; PETSCII code 202
|
||||
.byte $42, $44, $48, $7c, $62, $62, $62, $00 ; PETSCII code 203
|
||||
.byte $40, $40, $40, $60, $60, $60, $7e, $00 ; PETSCII code 204
|
||||
.byte $7e, $4a, $4a, $6a, $6a, $6a, $6a, $00 ; PETSCII code 205
|
||||
.byte $7e, $42, $42, $62, $62, $62, $62, $00 ; PETSCII code 206
|
||||
.byte $7e, $46, $42, $42, $42, $42, $7e, $00 ; PETSCII code 207
|
||||
.byte $7e, $42, $42, $7e, $60, $60, $60, $00 ; PETSCII code 208
|
||||
.byte $7e, $42, $42, $42, $4a, $4e, $7e, $00 ; PETSCII code 209
|
||||
.byte $7c, $44, $44, $7c, $62, $62, $62, $00 ; PETSCII code 210
|
||||
.byte $7e, $42, $40, $7e, $06, $46, $7e, $00 ; PETSCII code 211
|
||||
.byte $3e, $10, $10, $18, $18, $18, $18, $00 ; PETSCII code 212
|
||||
.byte $42, $42, $42, $62, $62, $62, $7e, $00 ; PETSCII code 213
|
||||
.byte $62, $62, $62, $66, $24, $24, $3c, $00 ; PETSCII code 214
|
||||
.byte $4a, $4a, $4a, $6a, $6a, $6a, $7e, $00 ; PETSCII code 215
|
||||
.byte $42, $42, $66, $3c, $66, $62, $62, $00 ; PETSCII code 216
|
||||
.byte $22, $22, $22, $3e, $18, $18, $18, $00 ; PETSCII code 217
|
||||
.byte $7e, $42, $06, $18, $60, $62, $7e, $00 ; PETSCII code 218
|
||||
.byte $08, $08, $08, $08, $ff, $08, $08, $08 ; PETSCII code 219
|
||||
.byte $a0, $50, $a0, $50, $a0, $50, $a0, $50 ; PETSCII code 220
|
||||
.byte $08, $08, $08, $08, $08, $08, $08, $08 ; PETSCII code 221
|
||||
.byte $cc, $cc, $33, $33, $cc, $cc, $33, $33 ; PETSCII code 222
|
||||
.byte $cc, $66, $33, $99, $cc, $66, $33, $99 ; PETSCII code 223
|
||||
.byte $00, $00, $00, $00, $00, $00, $00, $00 ; PETSCII code 224
|
||||
.byte $f0, $f0, $f0, $f0, $f0, $f0, $f0, $f0 ; PETSCII code 225
|
||||
.byte $00, $00, $00, $00, $ff, $ff, $ff, $ff ; PETSCII code 226
|
||||
.byte $ff, $00, $00, $00, $00, $00, $00, $00 ; PETSCII code 227
|
||||
.byte $00, $00, $00, $00, $00, $00, $00, $ff ; PETSCII code 228
|
||||
.byte $80, $80, $80, $80, $80, $80, $80, $80 ; PETSCII code 229
|
||||
.byte $aa, $55, $aa, $55, $aa, $55, $aa, $55 ; PETSCII code 230
|
||||
.byte $01, $01, $01, $01, $01, $01, $01, $01 ; PETSCII code 231
|
||||
.byte $00, $00, $00, $00, $aa, $55, $aa, $55 ; PETSCII code 232
|
||||
.byte $99, $33, $66, $cc, $99, $33, $66, $cc ; PETSCII code 233
|
||||
.byte $03, $03, $03, $03, $03, $03, $03, $03 ; PETSCII code 234
|
||||
.byte $08, $08, $08, $08, $0f, $08, $08, $08 ; PETSCII code 235
|
||||
.byte $00, $00, $00, $00, $0f, $0f, $0f, $0f ; PETSCII code 236
|
||||
.byte $08, $08, $08, $08, $0f, $00, $00, $00 ; PETSCII code 237
|
||||
.byte $00, $00, $00, $00, $f8, $08, $08, $08 ; PETSCII code 238
|
||||
.byte $00, $00, $00, $00, $00, $00, $ff, $ff ; PETSCII code 239
|
||||
.byte $00, $00, $00, $00, $0f, $08, $08, $08 ; PETSCII code 240
|
||||
.byte $08, $08, $08, $08, $ff, $00, $00, $00 ; PETSCII code 241
|
||||
.byte $00, $00, $00, $00, $ff, $08, $08, $08 ; PETSCII code 242
|
||||
.byte $08, $08, $08, $08, $f8, $08, $08, $08 ; PETSCII code 243
|
||||
.byte $c0, $c0, $c0, $c0, $c0, $c0, $c0, $c0 ; PETSCII code 244
|
||||
.byte $e0, $e0, $e0, $e0, $e0, $e0, $e0, $e0 ; PETSCII code 245
|
||||
.byte $07, $07, $07, $07, $07, $07, $07, $07 ; PETSCII code 246
|
||||
.byte $ff, $ff, $00, $00, $00, $00, $00, $00 ; PETSCII code 247
|
||||
.byte $ff, $ff, $ff, $00, $00, $00, $00, $00 ; PETSCII code 248
|
||||
.byte $00, $00, $00, $00, $00, $ff, $ff, $ff ; PETSCII code 249
|
||||
.byte $01, $02, $44, $48, $50, $60, $40, $00 ; PETSCII code 250
|
||||
.byte $00, $00, $00, $00, $f0, $f0, $f0, $f0 ; PETSCII code 251
|
||||
.byte $0f, $0f, $0f, $0f, $00, $00, $00, $00 ; PETSCII code 252
|
||||
.byte $08, $08, $08, $08, $f8, $00, $00, $00 ; PETSCII code 253
|
||||
.byte $f0, $f0, $f0, $f0, $00, $00, $00, $00 ; PETSCII code 254
|
||||
.byte $f0, $f0, $f0, $f0, $0f, $0f, $0f, $0f ; PETSCII code 255
|
File diff suppressed because it is too large
Load Diff
|
@ -3608,6 +3608,14 @@ void g_asr (unsigned flags, unsigned long val)
|
|||
}
|
||||
val -= 8;
|
||||
}
|
||||
if (val == 7) {
|
||||
if (flags & CF_UNSIGNED) {
|
||||
AddCodeLine ("jsr shrax7");
|
||||
} else {
|
||||
AddCodeLine ("jsr asrax7");
|
||||
}
|
||||
val = 0;
|
||||
}
|
||||
if (val >= 4) {
|
||||
if (flags & CF_UNSIGNED) {
|
||||
AddCodeLine ("jsr shrax4");
|
||||
|
@ -3751,6 +3759,14 @@ void g_asl (unsigned flags, unsigned long val)
|
|||
AddCodeLine ("lda #$00");
|
||||
val -= 8;
|
||||
}
|
||||
if (val == 7) {
|
||||
if (flags & CF_UNSIGNED) {
|
||||
AddCodeLine ("jsr shlax7");
|
||||
} else {
|
||||
AddCodeLine ("jsr aslax7");
|
||||
}
|
||||
val = 0;
|
||||
}
|
||||
if (val >= 4) {
|
||||
if (flags & CF_UNSIGNED) {
|
||||
AddCodeLine ("jsr shlax4");
|
||||
|
|
|
@ -99,6 +99,7 @@ static const FuncInfo FuncInfoTable[] = {
|
|||
{ "aslax2", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 },
|
||||
{ "aslax3", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 },
|
||||
{ "aslax4", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 },
|
||||
{ "aslax7", REG_AX, PSTATE_ALL | REG_AXY },
|
||||
{ "aslaxy", REG_AXY, PSTATE_ALL | REG_AXY | REG_TMP1 },
|
||||
{ "asleax1", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 },
|
||||
{ "asleax2", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 },
|
||||
|
@ -108,6 +109,7 @@ static const FuncInfo FuncInfoTable[] = {
|
|||
{ "asrax2", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 },
|
||||
{ "asrax3", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 },
|
||||
{ "asrax4", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 },
|
||||
{ "asrax7", REG_AX, PSTATE_ALL | REG_AX },
|
||||
{ "asraxy", REG_AXY, PSTATE_ALL | REG_AXY | REG_TMP1 },
|
||||
{ "asreax1", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 },
|
||||
{ "asreax2", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 },
|
||||
|
@ -245,6 +247,7 @@ static const FuncInfo FuncInfoTable[] = {
|
|||
{ "shlax2", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 },
|
||||
{ "shlax3", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 },
|
||||
{ "shlax4", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 },
|
||||
{ "shlax7", REG_AX, PSTATE_ALL | REG_AXY },
|
||||
{ "shlaxy", REG_AXY, PSTATE_ALL | REG_AXY | REG_TMP1 },
|
||||
{ "shleax1", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 },
|
||||
{ "shleax2", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 },
|
||||
|
@ -254,6 +257,7 @@ static const FuncInfo FuncInfoTable[] = {
|
|||
{ "shrax2", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 },
|
||||
{ "shrax3", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 },
|
||||
{ "shrax4", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 },
|
||||
{ "shrax7", REG_AX, PSTATE_ALL | REG_AX },
|
||||
{ "shraxy", REG_AXY, PSTATE_ALL | REG_AXY | REG_TMP1 },
|
||||
{ "shreax1", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 },
|
||||
{ "shreax2", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 },
|
||||
|
|
|
@ -1488,7 +1488,7 @@ static const OptFuncDesc FuncTable[] = {
|
|||
};
|
||||
|
||||
static const OptFuncDesc FuncRegATable[] = {
|
||||
{ "tosandax", Opt_a_tosand, REG_NONE, OP_NONE },
|
||||
{ "tosandax", Opt_a_tosand, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT },
|
||||
{ "toseqax", Opt_a_toseq, REG_NONE, OP_NONE },
|
||||
{ "tosgeax", Opt_a_tosuge, REG_NONE, OP_NONE },
|
||||
{ "tosgtax", Opt_a_tosugt, REG_NONE, OP_NONE },
|
||||
|
@ -1496,13 +1496,13 @@ static const OptFuncDesc FuncRegATable[] = {
|
|||
{ "tosleax", Opt_a_tosule, REG_NONE, OP_NONE },
|
||||
{ "tosltax", Opt_a_tosult, REG_NONE, OP_NONE },
|
||||
{ "tosneax", Opt_a_tosne, REG_NONE, OP_NONE },
|
||||
{ "tosorax", Opt_a_tosor, REG_NONE, OP_NONE },
|
||||
{ "tosorax", Opt_a_tosor, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT },
|
||||
{ "tossubax", Opt_a_tossub, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT },
|
||||
{ "tosugeax", Opt_a_tosuge, REG_NONE, OP_NONE },
|
||||
{ "tosugtax", Opt_a_tosugt, REG_NONE, OP_NONE },
|
||||
{ "tosuleax", Opt_a_tosule, REG_NONE, OP_NONE },
|
||||
{ "tosultax", Opt_a_tosult, REG_NONE, OP_NONE },
|
||||
{ "tosxorax", Opt_a_tosxor, REG_NONE, OP_NONE },
|
||||
{ "tosxorax", Opt_a_tosxor, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT },
|
||||
};
|
||||
|
||||
#define FUNC_COUNT(Table) (sizeof(Table) / sizeof(Table[0]))
|
||||
|
|
|
@ -163,7 +163,7 @@ static void PVArgs (CPURegs* Regs)
|
|||
|
||||
static void PVOpen (CPURegs* Regs)
|
||||
{
|
||||
char Path[PVOPEN_PATH_SIZE];
|
||||
char Path[PV_PATH_SIZE];
|
||||
int OFlag = O_INITIAL;
|
||||
int OMode = 0;
|
||||
unsigned RetVal, I = 0;
|
||||
|
@ -184,7 +184,7 @@ static void PVOpen (CPURegs* Regs)
|
|||
break;
|
||||
}
|
||||
++I;
|
||||
if (I >= PVOPEN_PATH_SIZE) {
|
||||
if (I >= PV_PATH_SIZE) {
|
||||
Error("PVOpen path too long at address $%04X",Name);
|
||||
}
|
||||
}
|
||||
|
@ -253,6 +253,35 @@ static void PVClose (CPURegs* Regs)
|
|||
|
||||
|
||||
|
||||
static void PVSysRemove (CPURegs* Regs)
|
||||
{
|
||||
char Path[PV_PATH_SIZE];
|
||||
unsigned RetVal, I = 0;
|
||||
|
||||
unsigned Name = GetAX (Regs);
|
||||
|
||||
Print (stderr, 2, "PVSysRemove ($%04X)\n", Name);
|
||||
|
||||
do {
|
||||
if (!(Path[I] = MemReadByte ((Name + I) & 0xFFFF))) {
|
||||
break;
|
||||
}
|
||||
++I;
|
||||
if (I >= PV_PATH_SIZE) {
|
||||
Error("PVSysRemove path too long at address $%04X", Name);
|
||||
}
|
||||
}
|
||||
while (1);
|
||||
|
||||
Print (stderr, 2, "PVSysRemove (\"%s\")\n", Path);
|
||||
|
||||
RetVal = remove (Path);
|
||||
|
||||
SetAX (Regs, RetVal);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void PVRead (CPURegs* Regs)
|
||||
{
|
||||
unsigned char* Data;
|
||||
|
@ -305,7 +334,17 @@ static void PVWrite (CPURegs* Regs)
|
|||
|
||||
|
||||
|
||||
static void PVOSMapErrno (CPURegs* Regs)
|
||||
{
|
||||
unsigned err = GetAX(Regs);
|
||||
SetAX (Regs, err != 0 ? -1 : 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const PVFunc Hooks[] = {
|
||||
PVSysRemove,
|
||||
PVOSMapErrno,
|
||||
PVOpen,
|
||||
PVClose,
|
||||
PVRead,
|
||||
|
|
|
@ -44,11 +44,11 @@
|
|||
|
||||
|
||||
|
||||
#define PARAVIRT_BASE 0xFFF4
|
||||
#define PARAVIRT_BASE 0xFFF2
|
||||
/* Lowest address used by a paravirtualization hook */
|
||||
|
||||
#define PVOPEN_PATH_SIZE 1024
|
||||
/* Maximum path size supported by PVOpen */
|
||||
#define PV_PATH_SIZE 1024
|
||||
/* Maximum path size supported by PVOpen/PVSysRemove */
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
!!DESCRIPTION!! fgets test
|
||||
!!LICENCE!! Public domain
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
FILE *in, *out;
|
||||
char buf[32];
|
||||
|
||||
#define INFILE "cf.in"
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
static char outfile_path[FILENAME_MAX+1];
|
||||
|
||||
sprintf(outfile_path, "%s.test.out", argv[0]);
|
||||
|
||||
out = fopen(outfile_path, "wb");
|
||||
if (out == NULL) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (fgets(buf, sizeof(buf), out) != NULL) {
|
||||
printf("Error, could fgets with write-only file\n");
|
||||
return 1;
|
||||
}
|
||||
if (!ferror(out)) {
|
||||
printf("Error: file pointer should be in error state\n");
|
||||
}
|
||||
fclose(out);
|
||||
unlink(outfile_path);
|
||||
|
||||
in = fopen(INFILE, "rb");
|
||||
if (in == NULL) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (fgets(NULL, 0, in) != NULL) {
|
||||
printf("Error, could fgets with zero size\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Test ungetc while we're at it */
|
||||
buf[0] = fgetc(in);
|
||||
ungetc(buf[0], in);
|
||||
|
||||
|
||||
while (fgets(buf, sizeof(buf), in) != NULL)
|
||||
{
|
||||
printf("%s",buf);
|
||||
}
|
||||
|
||||
if (!feof(in))
|
||||
{
|
||||
printf("We should have EOF!\n");
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
!!DESCRIPTION!! fgets test
|
||||
!!LICENCE!! Public domain
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
FILE *in, *out;
|
||||
int c, err;
|
||||
|
||||
#define INFILE "cf.in"
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
in = fopen(INFILE, "rb");
|
||||
if (in == NULL) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (fputc(c, in) != EOF) {
|
||||
printf("Error: can fputc to a file opened for reading\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
clearerr(in);
|
||||
|
||||
while ((c = fgetc(in)) != EOF) {
|
||||
fputc(c, stdout);
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
!!DESCRIPTION!! fgets test
|
||||
!!LICENCE!! Public domain
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
FILE *in, *out;
|
||||
char buf[512], err;
|
||||
|
||||
#define INFILE "cf.in"
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
in = fopen(INFILE, "rb");
|
||||
if (in == NULL) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
strcpy(buf, "test");
|
||||
if (fputs(buf, in) != EOF) {
|
||||
printf("Error: can fputs to a file opened for reading\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
clearerr(in);
|
||||
|
||||
while (fgets(buf, 512, in) != NULL) {
|
||||
fputs(buf, stdout);
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
!!DESCRIPTION!! fgets test
|
||||
!!LICENCE!! Public domain
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
FILE *in, *out;
|
||||
char buf[32];
|
||||
|
||||
#define INFILE "cf.in"
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
static char outfile_path[FILENAME_MAX+1];
|
||||
static int r;
|
||||
|
||||
sprintf(outfile_path, "%s.test.out", argv[0]);
|
||||
|
||||
out = fopen(outfile_path, "wb");
|
||||
if (out == NULL) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (fread(buf, 1, sizeof(buf), out) != NULL) {
|
||||
printf("Error, could fread with write-only file\n");
|
||||
return 1;
|
||||
}
|
||||
if (!ferror(out)) {
|
||||
printf("Error: file pointer should be in error state\n");
|
||||
}
|
||||
fclose(out);
|
||||
unlink(outfile_path);
|
||||
|
||||
in = fopen(INFILE, "rb");
|
||||
if (in == NULL) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Test that ungetc doesn't break fread */
|
||||
buf[0] = fgetc(in);
|
||||
ungetc(buf[0], in);
|
||||
|
||||
r = fread(buf, 1, sizeof(buf), out);
|
||||
|
||||
if (r == 0) {
|
||||
printf("Error: could not start reading.\n");
|
||||
}
|
||||
fwrite(buf, 1, r, stdout);
|
||||
|
||||
/* Finish reading file. */
|
||||
while ((r = fread(buf, 1, sizeof(buf), out)) != 0)
|
||||
{
|
||||
fwrite(buf, 1, r, stdout);
|
||||
}
|
||||
|
||||
if (!feof(in))
|
||||
{
|
||||
printf("We should have EOF!\n");
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
!!DESCRIPTION!! gets test
|
||||
!!LICENCE!! Public domain
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
|
||||
char buf[512];
|
||||
|
||||
#define INFILE "cf.in"
|
||||
|
||||
#ifndef __CC65__
|
||||
/* Force declaration on host compiler, as gets() is deprecated for
|
||||
* being dangerous as hell */
|
||||
char *gets (char *__s);
|
||||
#endif
|
||||
|
||||
#ifdef NO_OLD_FUNC_DECL
|
||||
int main(int argc,char **argv)
|
||||
#else
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
#endif
|
||||
{
|
||||
/* Fake stdin with the reference file */
|
||||
if (freopen(INFILE, "rb", stdin) == NULL) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
while (gets(buf) != NULL)
|
||||
{
|
||||
printf("%s",buf);
|
||||
}
|
||||
|
||||
fclose(stdin);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
/* bug #2395: Bitwise operators with a boolean expression fail when optimized */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
unsigned char a, b;
|
||||
unsigned char c = 199;
|
||||
unsigned char d = 100;
|
||||
|
||||
int main(void) {
|
||||
int fails = 0;
|
||||
|
||||
a = c ^ (d != 0);
|
||||
b = c ^ 1;
|
||||
|
||||
printf("%u ^ (%u != 0) => %u\n", c, d, a);
|
||||
if (a != b) {
|
||||
printf("XOR error: a %d instead of %d\n", a, b);
|
||||
fails++;
|
||||
}
|
||||
|
||||
a = c | (d != 0);
|
||||
b = c | 1;
|
||||
|
||||
printf("%u | (%u != 0) => %u\n", c, d, a);
|
||||
if (a != b) {
|
||||
printf("OR error: a %d instead of %d\n", a, b);
|
||||
fails++;
|
||||
}
|
||||
|
||||
a = c & (d != 0);
|
||||
b = c & 1;
|
||||
|
||||
printf("%u & (%u != 0) => %u\n", c, d, a);
|
||||
if (a != b) {
|
||||
printf("AND error: a %d instead of %d\n", a, b);
|
||||
fails++;
|
||||
}
|
||||
printf("%d errors\n", fails);
|
||||
|
||||
return fails;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "unittest.h"
|
||||
|
||||
TEST
|
||||
{
|
||||
char *buf, *buf2;
|
||||
unsigned int i;
|
||||
|
||||
buf = malloc(0);
|
||||
ASSERT_IsTrue (buf == NULL, "malloc (0) returned something");
|
||||
|
||||
for (i = 1; i < 10; i++) {
|
||||
buf = malloc(i);
|
||||
ASSERT_IsTrue (buf != NULL, "small returned nothing");
|
||||
}
|
||||
|
||||
buf = malloc(4096);
|
||||
ASSERT_IsTrue (buf != NULL, "malloc (4096) returned nothing");
|
||||
|
||||
buf = malloc(61000UL);
|
||||
ASSERT_IsTrue (buf == NULL, "malloc (61000) returned something");
|
||||
|
||||
for (i = 65535UL; i > _heapmaxavail(); i--) {
|
||||
buf = malloc(i);
|
||||
ASSERT_IsTrue (buf == NULL, "malloc returned something but shouldn't have");
|
||||
}
|
||||
|
||||
buf = malloc(i);
|
||||
ASSERT_IsTrue (buf != NULL, "malloc returned nothing but should have");
|
||||
ASSERT_IsTrue(_heapmaxavail() == 0, "heapmaxavail should be 0");
|
||||
}
|
||||
ENDTEST
|
|
@ -0,0 +1,31 @@
|
|||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include "unittest.h"
|
||||
|
||||
TEST
|
||||
{
|
||||
void *buf;
|
||||
int r;
|
||||
|
||||
r = posix_memalign(&buf, 123, 1024);
|
||||
ASSERT_IsTrue(r == EINVAL, "posix_memalign did not return EINVAL with wrong alignment");
|
||||
ASSERT_IsTrue(buf == NULL, "posix_memalign did not set buf to NULL with wrong alignment");
|
||||
|
||||
r = posix_memalign(&buf, 0, 1024);
|
||||
ASSERT_IsTrue(r == EINVAL, "posix_memalign did not return EINVAL with 0 alignment");
|
||||
ASSERT_IsTrue(buf == NULL, "posix_memalign did not set buf to NULL with 0 alignment");
|
||||
|
||||
r = posix_memalign(&buf, 256, 0);
|
||||
ASSERT_IsTrue(r == EINVAL, "posix_memalign did not return EINVAL with 0 size");
|
||||
ASSERT_IsTrue(buf == NULL, "posix_memalign did not set buf to NULL with 0 size");
|
||||
|
||||
r = posix_memalign(&buf, 256, 32768U);
|
||||
ASSERT_IsTrue(r == 0, "posix_memalign did not return 0 on correct call");
|
||||
ASSERT_IsTrue(buf != NULL, "posix_memalign left buf set to NULL on correct call");
|
||||
ASSERT_IsTrue(((unsigned int)buf & 0x00FF) == 0x00, "posix_memalign did not align memory");
|
||||
|
||||
r = posix_memalign(&buf, 256, 32768U);
|
||||
ASSERT_IsTrue(r == ENOMEM, "posix_memalign did not return ENOMEM when no memory is available");
|
||||
ASSERT_IsTrue(buf == NULL, "posix_memalign did not set buf to NULL when no memory is available");
|
||||
}
|
||||
ENDTEST
|
|
@ -0,0 +1,81 @@
|
|||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "unittest.h"
|
||||
|
||||
TEST
|
||||
{
|
||||
char *buf, *buf2;
|
||||
unsigned int i;
|
||||
|
||||
buf = realloc(NULL, 0);
|
||||
ASSERT_IsTrue (buf == NULL, "realloc (NULL, 0) returned something");
|
||||
|
||||
for (i = 1; i < 10; i++) {
|
||||
buf2 = realloc(buf, i);
|
||||
ASSERT_IsTrue (buf2 != NULL, "small realloc returned nothing");
|
||||
if (i > 1) {
|
||||
ASSERT_IsTrue (buf2 == buf, "buf shouldn't have moved");
|
||||
}
|
||||
buf = buf2;
|
||||
}
|
||||
|
||||
buf = realloc(NULL, 15);
|
||||
ASSERT_IsTrue (buf != NULL, "realloc (NULL, 15) returned nothing");
|
||||
|
||||
buf = realloc(buf, 0);
|
||||
ASSERT_IsTrue (buf == NULL, "realloc (buf, 0) returned something");
|
||||
|
||||
buf = realloc(buf, 32);
|
||||
memset(buf, 'a', 32);
|
||||
for (i = 0; i < 32; i++) {
|
||||
ASSERT_IsTrue(buf[i] == 'a', "wrong contents in buf");
|
||||
}
|
||||
|
||||
/* Now realloc larger, while there's nothing else in the heap */
|
||||
buf = realloc(buf, 64);
|
||||
memset(buf+32, 'b', 32);
|
||||
for (i = 0; i < 32; i++) {
|
||||
ASSERT_IsTrue(buf[i] == 'a', "wrong contents in start of buf");
|
||||
}
|
||||
for (i = 32; i < 64; i++) {
|
||||
ASSERT_IsTrue(buf[i] == 'b', "wrong contents in end of buf");
|
||||
}
|
||||
|
||||
/* Now realloc smaller, while there's nothing else in the heap */
|
||||
buf = realloc(buf, 40);
|
||||
for (i = 0; i < 32; i++) {
|
||||
ASSERT_IsTrue(buf[i] == 'a', "wrong contents in start of buf");
|
||||
}
|
||||
for (i = 32; i < 40; i++) {
|
||||
ASSERT_IsTrue(buf[i] == 'b', "wrong contents in end of buf");
|
||||
}
|
||||
|
||||
/* Allocate something else, so next realloc has to change block */
|
||||
malloc(50);
|
||||
|
||||
/* Now realloc larger, with something else in the heap */
|
||||
buf = realloc(buf, 128);
|
||||
for (i = 0; i < 32; i++) {
|
||||
ASSERT_IsTrue(buf[i] == 'a', "wrong contents in start of buf");
|
||||
}
|
||||
for (i = 32; i < 40; i++) {
|
||||
ASSERT_IsTrue(buf[i] == 'b', "wrong contents in end of buf");
|
||||
}
|
||||
|
||||
for (i = 129; i < 8192; i++) {
|
||||
buf = realloc(buf, i);
|
||||
ASSERT_IsTrue(buf != NULL, "realloc failed");
|
||||
}
|
||||
|
||||
malloc(4096);
|
||||
|
||||
buf2 = realloc(buf, 58000UL);
|
||||
ASSERT_IsTrue (buf2 == NULL, "realloc (buf, 58000) returned something");
|
||||
|
||||
for (i = 65535UL; i > 65527UL; i--) {
|
||||
buf2 = realloc(buf, i);
|
||||
ASSERT_IsTrue (buf2 == NULL, "realloc returned something but shouldn't have");
|
||||
}
|
||||
}
|
||||
ENDTEST
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
!!DESCRIPTION!! A small test for aslax7.
|
||||
!!ORIGIN!!
|
||||
!!LICENCE!!
|
||||
!!AUTHOR!!
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
signed int ai = -32768, ti, refi;
|
||||
signed char ac = -128, tc, refc;
|
||||
|
||||
do {
|
||||
refi = ai << 4;
|
||||
refi = refi << 3;
|
||||
|
||||
ti = ai << 7;
|
||||
|
||||
if (ti != refi) {
|
||||
printf("wrong result on int %d << 7: %04X, expected %04X\n", ai, ti, refi);
|
||||
return 1;
|
||||
}
|
||||
} while (++ai != -32768);
|
||||
|
||||
do {
|
||||
refc = ac << 4;
|
||||
refc = refc << 3;
|
||||
|
||||
tc = ac << 7;
|
||||
|
||||
if (tc != refc) {
|
||||
printf("wrong result on char %d << 7: %04X, expected %04X\n", ac, tc, refc);
|
||||
return 1;
|
||||
}
|
||||
} while (++ac != -128);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
!!DESCRIPTION!! A small test for asrax7.
|
||||
!!ORIGIN!!
|
||||
!!LICENCE!!
|
||||
!!AUTHOR!!
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
signed int ai = -32768, ti, refi;
|
||||
signed char ac = -128, tc, refc;
|
||||
|
||||
do {
|
||||
refi = ai >> 4;
|
||||
refi = refi >> 3;
|
||||
|
||||
ti = ai >> 7;
|
||||
|
||||
if (ti != refi) {
|
||||
printf("wrong result on int %d >> 7: %04X, expected %04X\n", ai, ti, refi);
|
||||
return 1;
|
||||
}
|
||||
} while (++ai != -32768);
|
||||
|
||||
do {
|
||||
refc = ac >> 4;
|
||||
refc = refc >> 3;
|
||||
|
||||
tc = ac >> 7;
|
||||
|
||||
if (tc != refc) {
|
||||
printf("wrong result on char %d >> 7: %04X, expected %04X\n", ac, tc, refc);
|
||||
return 1;
|
||||
}
|
||||
} while (++ac != -128);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
!!DESCRIPTION!! A small test for shlax7.
|
||||
!!ORIGIN!!
|
||||
!!LICENCE!!
|
||||
!!AUTHOR!!
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
unsigned int ai = 0, ti, refi;
|
||||
unsigned char ac = 0, tc, refc;
|
||||
|
||||
do {
|
||||
refi = ai << 4;
|
||||
refi = refi << 3;
|
||||
|
||||
ti = ai << 7;
|
||||
|
||||
if (ti != refi) {
|
||||
printf("wrong result on int %u << 7: %04X, expected %04X\n", ai, ti, refi);
|
||||
return 1;
|
||||
}
|
||||
} while (++ai != 0);
|
||||
|
||||
do {
|
||||
refc = ac << 4;
|
||||
refc = refc << 3;
|
||||
|
||||
tc = ac << 7;
|
||||
|
||||
if (tc != refc) {
|
||||
printf("wrong result on char %u << 7: %04X, expected %04X\n", ac, tc, refc);
|
||||
return 1;
|
||||
}
|
||||
} while (++ac != 0);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
!!DESCRIPTION!! A small test for shrax7.
|
||||
!!ORIGIN!!
|
||||
!!LICENCE!!
|
||||
!!AUTHOR!!
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
unsigned int ai = 0, ti, refi;
|
||||
unsigned char ac = 0, tc, refc;
|
||||
|
||||
do {
|
||||
refi = ai >> 4;
|
||||
refi = refi >> 3;
|
||||
|
||||
ti = ai >> 7;
|
||||
|
||||
if (ti != refi) {
|
||||
printf("wrong result on int %d >> 7: %04X, expected %04X\n", ai, ti, refi);
|
||||
return 1;
|
||||
}
|
||||
} while (++ai != 0);
|
||||
|
||||
do {
|
||||
refc = ac >> 4;
|
||||
refc = refc >> 3;
|
||||
|
||||
tc = ac >> 7;
|
||||
|
||||
if (tc != refc) {
|
||||
printf("wrong result on char %d >> 7: %04X, expected %04X\n", ac, tc, refc);
|
||||
return 1;
|
||||
}
|
||||
} while (++ac != 0);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int fails = 0;
|
||||
|
||||
|
||||
static void create_out_file(const char *outfile_path) {
|
||||
FILE *out;
|
||||
|
||||
|
||||
out = fopen(outfile_path, "wb");
|
||||
if (out == NULL) {
|
||||
printf("Could not create %s\n", outfile_path);
|
||||
fails++;
|
||||
return;
|
||||
}
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int r;
|
||||
static char outfile_path[FILENAME_MAX+1];
|
||||
|
||||
sprintf(outfile_path, "%s.test.out", argv[0]);
|
||||
|
||||
create_out_file(outfile_path);
|
||||
r = remove(outfile_path);
|
||||
if (r != 0) {
|
||||
printf("could not remove() %s\n", outfile_path);
|
||||
fails++;
|
||||
}
|
||||
|
||||
create_out_file(outfile_path);
|
||||
r = unlink(outfile_path);
|
||||
if (r != 0) {
|
||||
printf("could not unlink() %s\n", outfile_path);
|
||||
fails++;
|
||||
}
|
||||
|
||||
r = remove("klsdfjqlsjdflkqjdsoizu");
|
||||
if (r == 0) {
|
||||
printf("remove()ing non-existent file succeeded\n");
|
||||
fails++;
|
||||
}
|
||||
|
||||
r = unlink("klsdfjqlsjdflkqjdsoizu");
|
||||
if (r == 0) {
|
||||
printf("unlink()ing non-existent file succeeded\n");
|
||||
fails++;
|
||||
}
|
||||
|
||||
return fails;
|
||||
}
|
Loading…
Reference in New Issue