From: uz Date: Sun, 22 Jul 2012 11:07:46 +0000 (+0000) Subject: Rewrote tgi_load_driver in assembler and fixed a possible memory leak when X-Git-Tag: V2.14~282 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=975a06c2eecf8c606d16a3624a19fdcbd981203e;p=cc65 Rewrote tgi_load_driver in assembler and fixed a possible memory leak when doing so. Changed the behaviour in case a driver is already loaded: Since the library cannot know if this driver was linked statically or loaded dynamically, an already installed driver is considered an error. It must be removed before calling tgi_load_driver. git-svn-id: svn://svn.cc65.org/cc65/trunk@5790 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/asminc/tgi-error.inc b/asminc/tgi-error.inc index b375918a6..0e026ee1b 100644 --- a/asminc/tgi-error.inc +++ b/asminc/tgi-error.inc @@ -6,7 +6,7 @@ ;* */ ;* */ ;* */ -;* (C) 2002-2009, Ullrich von Bassewitz */ +;* (C) 2002-2012, Ullrich von Bassewitz */ ;* Roemerstrasse 52 */ ;* D-70794 Filderstadt */ ;* EMail: uz@cc65.org */ @@ -45,6 +45,7 @@ TGI_ERR_INV_FONT ; Font file is invalid TGI_ERR_NO_RES ; Out of resources (memory, handles, ...) TGI_ERR_UNKNOWN ; Unknown error + TGI_ERR_INSTALLED ; A driver is already installed TGI_ERR_COUNT ; Special: Number of error messages .endenum diff --git a/asminc/tgi-kernel.inc b/asminc/tgi-kernel.inc index 6eabe9a3b..9061fe9af 100644 --- a/asminc/tgi-kernel.inc +++ b/asminc/tgi-kernel.inc @@ -6,7 +6,7 @@ ;* */ ;* */ ;* */ -;* (C) 2002-2009, Ullrich von Bassewitz */ +;* (C) 2002-2012, Ullrich von Bassewitz */ ;* Roemerstrasse 52 */ ;* D-70794 Filderstadt */ ;* EMail: uz@cc65.org */ @@ -170,6 +170,7 @@ TGI_CLIP_TOP = $08 ;------------------------------------------------------------------------------ ; ASM functions + .global tgi_clear_ptr .global tgi_clippedline .global tgi_curtoxy .global tgi_getset diff --git a/include/tgi/tgi-error.h b/include/tgi/tgi-error.h index 11c97e337..e8dd9c236 100644 --- a/include/tgi/tgi-error.h +++ b/include/tgi/tgi-error.h @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2002-2009, Ullrich von Bassewitz */ +/* (C) 2002-2012, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -53,6 +53,7 @@ #define TGI_ERR_INV_FUNC 6 /* Function not supported */ #define TGI_ERR_INV_FONT 7 /* Font file is invalid */ #define TGI_ERR_NO_RES 8 /* Out of resources */ +#define TGI_ERR_INSTALLED 9 /* A driver is already installed */ diff --git a/libsrc/tgi/Makefile b/libsrc/tgi/Makefile index c1a8b4187..086f98c56 100644 --- a/libsrc/tgi/Makefile +++ b/libsrc/tgi/Makefile @@ -30,7 +30,6 @@ CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include # Object files C_OBJS = tgi_arc.o \ - tgi_load_driver.o \ tgi_load_vectorfont.o \ tgi_pieslice.o @@ -68,6 +67,7 @@ S_OBJS = tgi-kernel.o \ tgi_line.o \ tgi_linepop.o \ tgi_lineto.o \ + tgi_load.o \ tgi_outcode.o \ tgi_outtext.o \ tgi_outtextxy.o \ diff --git a/libsrc/tgi/tgi-kernel.s b/libsrc/tgi/tgi-kernel.s index 74995412a..cfdd375b2 100644 --- a/libsrc/tgi/tgi-kernel.s +++ b/libsrc/tgi/tgi-kernel.s @@ -201,6 +201,7 @@ _tgi_uninstall: ; Clear driver pointer and error code +tgi_clear_ptr: lda #$00 sta _tgi_drv sta _tgi_drv+1 diff --git a/libsrc/tgi/tgi_geterrormsg.s b/libsrc/tgi/tgi_geterrormsg.s index b7cfd87c1..d683a1ad5 100644 --- a/libsrc/tgi/tgi_geterrormsg.s +++ b/libsrc/tgi/tgi_geterrormsg.s @@ -41,6 +41,7 @@ offs: .byte <(msg0-msgtab) .byte <(msg7-msgtab) .byte <(msg8-msgtab) .byte <(msg9-msgtab) + .byte <(msg10-msgtab) msgtab: msg0: .asciiz "No error" @@ -53,4 +54,6 @@ msg6: .asciiz "Function not supported" msg7: .asciiz "Invalid font file" msg8: .asciiz "Out of resources" msg9: .asciiz "Unknown error" +msg10: .asciiz "A driver is already installed" +.assert (*-msgtab) < 256, error, "Message table too large" diff --git a/libsrc/tgi/tgi_load.s b/libsrc/tgi/tgi_load.s new file mode 100644 index 000000000..9ce438066 --- /dev/null +++ b/libsrc/tgi/tgi_load.s @@ -0,0 +1,118 @@ +; +; Ullrich von Bassewitz, 2012-07-22 +; +; void __fastcall__ tgi_load_driver (const char* name); +; /* Load and install the given driver. */ + + + .include "tgi-kernel.inc" + .include "tgi-error.inc" + .include "modload.inc" + .include "fcntl.inc" + + .import pushax + .import pusha0 + .import incsp2 + .import _open + .import _read + .import _close + + + +;---------------------------------------------------------------------------- +; Variables + +.data + +ctrl: .addr _read + .res 2 ; CALLERDATA + .res 2 ; MODULE + .res 2 ; MODULE_SIZE + .res 2 ; MODULE_ID + +;---------------------------------------------------------------------------- +; Code + +.code + +.proc _tgi_load_driver + +; Check if we do already have a driver loaded. This is an error. Do not +; touch A/X because they contain the file name. + + ldy _tgi_drv + bne @L0 + ldy _tgi_drv+1 + beq @L1 +@L0: lda #TGI_ERR_INSTALLED + bne @L3 + +; Push the name onto the C stack and open the file. The parameter will get +; removed by open(). +; ctrl.callerdata = open (name, O_RDONLY); + +@L1: jsr pushax + lda #= 0) { + + txa + bmi @L2 + +; /* Load the module */ +; Res = mod_load (&ctrl); + + lda #ctrl + jsr _mod_load + pha + +; /* Close the input file */ +; close (ctrl.callerdata); + + lda ctrl + MOD_CTRL::CALLERDATA + ldx ctrl + MOD_CTRL::CALLERDATA+1 + jsr _close + +; /* Check the return code */ +; if (Res == MLOAD_OK) { + + pla + beq @L5 +@L2: lda #TGI_ERR_CANNOT_LOAD + +; Set an error and exit + +@L3: sta _tgi_error +@L4: rts + +; Check the driver signature, install the driver. c is already on stack and +; will get removed by ser_install(). +; Res = ser_install (ctrl.module); + +@L5: lda ctrl + MOD_CTRL::MODULE + ldx ctrl + MOD_CTRL::MODULE+1 + jsr _tgi_install + +; If tgi_install was successful, we're done + + lda _tgi_error + beq @L4 + +; The driver didn't install correctly. Remove it from memory. The error code +; will be retained. + + lda _tgi_drv + ldx _tgi_drv+1 + jsr _mod_free ; Free the driver memory + jmp tgi_clear_ptr ; Clear tgi_drv and return + +.endproc + + + diff --git a/libsrc/tgi/tgi_load_driver.c b/libsrc/tgi/tgi_load_driver.c deleted file mode 100644 index e4319e00f..000000000 --- a/libsrc/tgi/tgi_load_driver.c +++ /dev/null @@ -1,88 +0,0 @@ -/*****************************************************************************/ -/* */ -/* tgi_load_driver.c */ -/* */ -/* Loader module for TGI drivers */ -/* */ -/* */ -/* */ -/* (C) 2002-2009, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* 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 -#include -#include -#include -#include - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -void __fastcall__ tgi_load_driver (const char* name) -/* Install the given driver. This function is identical to tgi_load with the - * only difference that the name of the driver is specified explicitly. You - * should NOT use this function in most cases, use tgi_load() instead. - */ -{ - static struct mod_ctrl ctrl = { - read /* Read from disk */ - }; - unsigned Res; - - /* Check if we do already have a driver loaded. If so, remove it. */ - if (tgi_drv != 0) { - tgi_unload (); - } - - /* Now open the file */ - ctrl.callerdata = open (name, O_RDONLY); - if (ctrl.callerdata >= 0) { - - /* Load the module */ - Res = mod_load (&ctrl); - - /* Close the input file */ - close (ctrl.callerdata); - - /* Check the return code */ - if (Res == MLOAD_OK) { - - /* Check the driver signature, install the driver */ - tgi_install (ctrl.module); - return; - - } - } - - /* Error loading the driver */ - tgi_error = TGI_ERR_CANNOT_LOAD; -}