; */
.global _mod_load
-; void mod_free (struct mod_ctrl* ctrl);
-; /* Free a loaded module. */
+; void mod_free (void* module);
+; /* Free a loaded module. Note: The given pointer is the pointer to the
+; * module memory, not a pointer to a control structure.
+; */
.global _mod_free
; Error constants
-TGI_ERR_OK = 0 ; No error
-TGI_ERR_NO_DRIVER = 1 ; No driver available
-TGI_ERR_LOAD_ERROR = 2 ; Error loading driver
-TGI_ERR_INV_MODE = 3 ; Mode not supported by driver
+TGI_ERR_OK = 0 ; No error
+TGI_ERR_NO_DRIVER = 1 ; No driver available
+TGI_ERR_LOAD_ERROR = 2 ; Error loading driver
+TGI_ERR_INV_DRIVER = 3 ; Invalid driver
+TGI_ERR_INV_MODE = 4 ; Mode not supported by driver
.global tgi_fetch_error
.global tgi_set_ptr
- .global tgi_setup
* loaded.
*/
-void mod_free (struct mod_ctrl* ctrl);
-/* Free a loaded module. */
+void mod_free (void* module);
+/* Free a loaded module. Note: The given pointer is the pointer to the
+ * module memory, not a pointer to a control structure.
+ */
#define TGI_ERR_OK 0 /* No error */
#define TGI_ERR_NO_DRIVER 1 /* No driver available */
-#define TGI_ERR_LOAD_ERROR 2 /* Error loading driver */
-#define TGI_ERR_INV_MODE 3 /* Mode not supported by driver */
+#define TGI_ERR_CANNOT_LOAD 2 /* Error loading driver */
+#define TGI_ERR_INV_DRIVER 3 /* Invalid driver */
+#define TGI_ERR_INV_MODE 4 /* Mode not supported by driver */
/* TGI kernel variables */
-extern tgi_drv_header tgi_drv; /* Pointer to driver */
-extern unsigned char tgi_error; /* Last error code */
+extern tgi_drv_header* tgi_drv; /* Pointer to driver */
+extern unsigned char tgi_error; /* Last error code */
extern unsigned char tgi_mode; /* Graphics mode or zero */
const char* __fastcall__ tgi_map_mode (unsigned char mode);
/* Map a tgi mode to a driver name. Returns NULL if no driver available. */
+
+void __fastcall__ tgi_setup (void);
+/* Setup the driver and graphics kernel once the driver is loaded */
-
+
# C64
c64lib:
- for i in c64 cbm common runtime conio dbg; do \
+ for i in c64 cbm common runtime conio dbg tgi; do \
CC=$(CC) \
AS=$(AS) \
CFLAGS="-Osir -g -T -t c64 -I../../include" \
$(MAKE) -C $$i || exit 1; \
done
mv c64/crt0.o c64.o
- for i in c64 cbm common runtime conio dbg; do \
+ for i in c64 cbm common runtime conio dbg tgi; do \
$(AR) a c64.lib $$i/*.o;\
done
--- /dev/null
+tgi_load.s
#
-# makefile for the TGI graphics kernel
+# Makefile for the TGI graphics kernel
#
.SUFFIXES: .o .s .c
%.o: %.s
@$(AS) -g -o $@ $(AFLAGS) $<
-C_OBJS =
+C_OBJS = tgi_load.o
S_OBJS = tgi-kernel.o \
tgi_bar.o \
.include "tgi-kernel.inc"
+ .export _tgi_setup
.importzp ptr1
.data
-
+
; Jump table for the driver functions.
tgi_install: jmp $0000
tgi_deinstall: jmp $0000
tgi_init: jmp $0000
-tgi_post: jmp $0000
+tgi_done: jmp $0000
tgi_control: jmp $0000
tgi_clear: jmp $0000
tgi_setcolor: jmp $0000
;----------------------------------------------------------------------------
-; Setup the TGI driver once it is loaded.
-
-tgi_setup:
- lda _tgi_drv
- sta ptr1
- lda _tgi_drv+1
- sta ptr1+1
+; void __fastcall__ tgi_setup (void);
+; /* Setup the driver and graphics kernel once the driver is loaded */
- ldy #TGI_HDR_JUMPTAB
- ldx #1
-@L1: lda (ptr1),y
+copy: lda (ptr1),y
sta tgi_install,x
iny
inx
- lda (ptr1),y
- sta tgi_install,x
- inx
+ rts
+
+
+_tgi_setup:
+ jsr tgi_set_ptr
+
+ ldy #TGI_HDR_JUMPTAB
+ ldx #0
+
+@L1: inx ; Skip JMP opcode
+ jsr copy ; Copy one byte
+ jsr copy ; Copy one byte
cpx #(TGI_HDR_JUMPCOUNT*3)
bne @L1
-
+
; Initialize variables
lda #$00
;----------------------------------------------------------------------------
; Fetch the error code from the driver and place it into the global error
-; variable.
+; variable. The function will also return the error in A and the flags from
+; loading the error code are set.
tgi_fetch_error:
jsr tgi_set_ptr
beq @L1 ; Jump if not
jsr tgi_done ; Call the driver routine
jsr tgi_fetch_error ; Get the error code
- lda _tgi_error ; Did we have an error?
- bne @L1 ; Jump if yes
- sta _tgi_mode ; Reset the current mode
+ bne @L1 ; Jump if we had an error
+ sta _tgi_mode ; Reset the current mode (A = 0)
@L1: rts
; Ullrich von Bassewitz, 21.06.2002
;
; unsigned char __fastcall__ tgi_geterror (void);
-; /* Return the error code for the last operation. This will also clear the
-; * error.
+; /* Return the error code for the last operation. This will also clear the
+; * error.
; */
.include "tgi-kernel.inc"
+ .export _tgi_geterror
_tgi_geterror:
ldx #0
_tgi_init:
pha ; Save mode
jsr _tgi_done ; Switch off graphics if needed
- jsr tgi_init ; Initialize the mode
+ pla
+ sta _tgi_mode ; Remember the mode
+ jsr tgi_init ; Go into graphics mode
jsr tgi_fetch_error ; Get the error code
- pla ; Restore the mode
- ldx _tgi_error ; Did we have an error before?
- bne @L1 ; Jump if yes
- sta _tgi_mode ; Set the current mode if not
+ beq @L1 ; Jump if no error
+ lda #$00
+ sta _tgi_mode ; Clear the mode if init was not successful
@L1: rts
--- /dev/null
+/*
+ * TEST VERSION - CURRENTLY C64 SPECIFIC!!!
+ */
+
+
+
+#include <string.h>
+#include <cbm.h>
+#include <modload.h>
+#include <tgi.h>
+#include <tgi/tgi-kernel.h>
+
+
+
+static unsigned char ReadInputBlock (struct mod_ctrl* C, void* Buf, unsigned Size)
+{
+ return (cbm_read (1, Buf, Size) != Size);
+}
+
+
+
+void __fastcall__ tgi_load (unsigned char mode)
+/* Install the matching driver for the given mode. Will just load the driver
+ * and check if loading was successul. Will not switch to gaphics mode.
+ */
+{
+ const char* name = tgi_map_mode (mode);
+ if (name == 0) {
+ /* No driver for this mode */
+ tgi_error = TGI_ERR_NO_DRIVER;
+ } else {
+ /* Laod the driver */
+ tgi_load_driver (name);
+ }
+}
+
+
+
+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 const unsigned char marker[4] = { 0x74, 0x67, 0x69, 0x00 };
+
+ static struct mod_ctrl ctrl = {
+ ReadInputBlock /* read_block */
+ };
+ 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 */
+ if (cbm_open (1, 8, 2, name) != 0) {
+ tgi_error = TGI_ERR_CANNOT_LOAD;
+ return;
+ }
+
+ /* Load the module */
+ Res = mod_load (&ctrl);
+ cbm_close (1);
+
+ /* Check the return code */
+ if (Res == MLOAD_OK) {
+
+ /* Get a pointer to the loaded driver */
+ tgi_drv = (tgi_drv_header*) ctrl.module;
+
+ /* Check the header */
+ if (memcmp (tgi_drv, marker, sizeof (marker)) != 0) {
+ /* Invalid driver */
+ mod_free (tgi_drv);
+ tgi_drv = 0;
+ tgi_error = TGI_ERR_INV_DRIVER;
+ } else {
+ /* Driver is ok do setup */
+ tgi_setup ();
+ }
+
+ } else {
+
+ /* Error loading the driver */
+ tgi_error = TGI_ERR_CANNOT_LOAD;
+
+ }
+}