From eef80e2199983d2654db117bc0b46cd5bf0a5aa8 Mon Sep 17 00:00:00 2001 From: d0p1 Date: Sun, 25 Feb 2024 16:58:08 +0100 Subject: [PATCH] WIP work on VM. Also add program icon --- bios/main.s | 18 ++++++ configure.ac | 43 +++++++++++++- disas/Makefile.am | 4 +- disas/main.c | 114 +++++++++++++++++++++++++++++------- disas/res/Makefrag.am | 8 +++ disas/res/disas.ico | Bin 0 -> 1662 bytes disas/res/disas.png | Bin 0 -> 1114 bytes disas/res/windows.rc | 1 + lib/op.h | 24 ++++++++ vm/Makefile.am | 10 +++- vm/ata/Makefrag.am | 7 +++ vm/ata/ata.c | 27 +++++++++ vm/ata/ata.h | 19 ++++++ vm/ata/ethernet.c | 14 +++++ vm/ata/rtc.c | 45 ++++++++++++++ vm/ata/serial.c | 25 ++++++++ vm/ata/vga.c | 22 +++++++ vm/bus.c | 19 ++++++ vm/jit/Makefrag.am | 7 +++ vm/{ => jit}/jit.c | 0 vm/{ => jit}/jit.h | 0 vm/{ => jit}/x64/register.h | 0 vm/{ => jit}/x64/x64.S | 0 vm/main.c | 10 ++++ vm/res/Makefrag.am | 8 +++ vm/res/vm.ico | Bin 0 -> 3774 bytes vm/res/vm.png | Bin 0 -> 1001 bytes vm/res/windows.rc | 1 + 28 files changed, 401 insertions(+), 25 deletions(-) create mode 100644 bios/main.s create mode 100644 disas/res/Makefrag.am create mode 100644 disas/res/disas.ico create mode 100644 disas/res/disas.png create mode 100644 disas/res/windows.rc create mode 100644 vm/ata/Makefrag.am create mode 100644 vm/ata/ata.c create mode 100644 vm/ata/ata.h create mode 100644 vm/ata/ethernet.c create mode 100644 vm/ata/rtc.c create mode 100644 vm/ata/serial.c create mode 100644 vm/ata/vga.c create mode 100644 vm/bus.c create mode 100644 vm/jit/Makefrag.am rename vm/{ => jit}/jit.c (100%) rename vm/{ => jit}/jit.h (100%) rename vm/{ => jit}/x64/register.h (100%) rename vm/{ => jit}/x64/x64.S (100%) create mode 100644 vm/res/Makefrag.am create mode 100644 vm/res/vm.ico create mode 100644 vm/res/vm.png create mode 100644 vm/res/windows.rc diff --git a/bios/main.s b/bios/main.s new file mode 100644 index 0000000..eae3f92 --- /dev/null +++ b/bios/main.s @@ -0,0 +1,18 @@ +.sect .text +.sect .rom +.sect .data +.sect .bss + +.sect .bss +STACKSIZE = 512 +.comm stack, STACKSIZE + +.sect .text +_start: + sei ! disable interrupt + + ! setup stack + ldy.l #stack + STACKSIZE + txs + + diff --git a/configure.ac b/configure.ac index 7afb2c2..392daac 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,18 @@ AC_INIT([65oo2], [1.0]) +AC_CANONICAL_HOST + AM_INIT_AUTOMAKE([foreign subdir-objects]) -AC_CANONICAL_HOST +AC_CONFIG_HEADERS([config.h]) + +case "$host_os" in + cygwin*|mingw*) + OS_TYPE=windows;; + *) + OS_TYPE=unknown;; +esac +AM_CONDITIONAL([OS_WINDOWS], test "$OS_TYPE" = "windows") AC_LANG(C) AC_PROG_CC @@ -12,10 +22,41 @@ AC_PROG_RANLIB AM_PROG_AS AM_PROG_AR AM_PROG_CC_C_O +PKG_PROG_PKG_CONFIG +AC_CHECK_TOOLS(WINDRES, [windres], :) + +AC_ARG_ENABLE([ata-vga], + [AS_HELP_STRING([--enable-ata-vga], [enable VGA (default=yes)])], + [WANT_ATA_VGA=$enableval], [WANT_ATA_VGA=yes]) +AC_ARG_ENABLE([ata-ethernet], + [AS_HELP_STRING([--enable-ata-ethernet], [enable ethernet device (default=yes)])], + [WANT_ATA_ETHERNET=$enableval], [WANT_ATA_ETHERNET=yes]) + +AC_ARG_ENABLE(mmu, + [AS_HELP_STRING([--enable-mmu], [enable MMU (default=yes)])], + [WANT_MMU=$enableval], [WANT_MMU=yes]) +AC_ARG_ENABLE(jit, + [AS_HELP_STRING([--enable-jit], [enable JIT compiler (default=no)])], + [WANT_JIT=$enableval], [WANT_JIT=no]) AC_CHECK_INCLUDES_DEFAULT AC_C_CONST +AM_CONDITIONAL([USE_ATA_VGA], test "$WANT_ATA_VGA" = "yes") +if test "$WANT_ATA_VGA" = "yes"; then + AC_DEFINE([ATA_VGA], [1], [Enable VGA device]) + PKG_CHECK_MODULES([SDL2], [sdl2]) + +fi + +AM_CONDITIONAL([USE_ATA_ETHERNET], test "$WANT_ATA_ETHERNET" = "yes") +if test "$WANT_ATA_ETHERNET" = "yes"; then + AC_DEFINE([ATA_ETERNET], [1], [Enable Ethernet device]) +fi + +AM_CONDITIONAL([USE_MMU], test "$WANT_MMU" = "yes") +AM_CONDITIONAL([USE_JIT], test "$WANT_JIT" = "yes") + AC_CONFIG_FILES([ Makefile lib/Makefile diff --git a/disas/Makefile.am b/disas/Makefile.am index 854cd05..ef68a59 100644 --- a/disas/Makefile.am +++ b/disas/Makefile.am @@ -1,5 +1,7 @@ +include res/Makefrag.am + bin_PROGRAMS = disas disas_SOURCES = main.c disas_CFLAGS =-I$(top_srcdir) -disas_LDADD = ../lib/lib65oo2.a \ No newline at end of file +disas_LDADD = ../lib/lib65oo2.a $(RES) \ No newline at end of file diff --git a/disas/main.c b/disas/main.c index 4b41cf7..89314e3 100644 --- a/disas/main.c +++ b/disas/main.c @@ -90,35 +90,67 @@ fatal(const char *str, ...) exit(EXIT_FAILURE); } +void +decode_target_suffix(uint8_t attr) +{ + fprintf(output, "."); + if (IS_TARGET_ZEXT(attr)) + { + fprintf(output, "U"); + } + + switch (GET_TARGET_SIZE(attr)) + { + case SIZE_BYTE: + fprintf(output, "B"); + break; + case SIZE_WORD: + fprintf(output, "W"); + break; + case SIZE_LONG: + fprintf(output, "L"); + break; + } +} + +void +decode_address(uint8_t attr) +{ + switch (GET_ADDRESS_SIZE(attr)) + { + case SIZE_BYTE: + fprintf(output, " %%%X", readu8()); + break; + case SIZE_WORD: + fprintf(output, " %%%hX", readu16()); + break; + case SIZE_LONG: + fprintf(output, " %%%X", readu32()); + break; + default: + break; + } +} + void decode_imm(uint8_t opcode) { uint8_t attr; attr = readu8(); - if ((attr & 0x3) == 0x3) - { - fprintf(output, "???\n"); - return; - } - fprintf(output, "%s.", opcode_str[opcode]); - - if (attr & 0x4) + fprintf(output, "%s", opcode_str[opcode]); + decode_target_suffix(attr); + switch (GET_TARGET_SIZE(attr)) { - fprintf(output, "U"); - } - - switch (attr & 0x3) - { - case 0x0: - fprintf(output, "B #$%X\n", readu8()); + case SIZE_BYTE: + fprintf(output, " #$%X\n", readu8()); break; - case 0x1: - fprintf(output, "W #$%hX\n", readu16()); + case SIZE_WORD: + fprintf(output, " #$%hX\n", readu16()); break; - case 0x2: - fprintf(output, "L #$%X\n", readu32()); + case SIZE_LONG: + fprintf(output, " #$%X\n", readu32()); break; default: break; @@ -130,8 +162,32 @@ decode_ind(uint8_t opcode) { uint8_t attr; + fprintf(output, "%s", opcode_str[opcode]); attr = readu8(); - (void)attr; + if (opcode != OP_JMP_ind) + { + decode_target_suffix(attr); + } + if (opcode_addr[opcode] & (OP_ADDR_X | OP_ADDR_Y)) + { + fprintf(output, " ("); + } + else + { + fprintf(output, " "); + } + + decode_address(attr); + + if (opcode_addr[opcode] & OP_ADDR_X) + { + fprintf(output, ", X)"); + } + else if (opcode_addr[opcode] & OP_ADDR_Y) + { + fprintf(output, "), Y"); + } + fprintf(output, "\n"); } void @@ -139,8 +195,24 @@ decode_abs(uint8_t opcode) { uint8_t attr; + fprintf(output, "%s", opcode_str[opcode]); attr = readu8(); - (void)attr; + if (opcode != OP_JSR_abs + || opcode != OP_JMP_abs) + { + decode_target_suffix(attr); + } + decode_address(attr); + + if (opcode_addr[opcode] & OP_ADDR_X) + { + fprintf(output, ", X"); + } + else if (opcode_addr[opcode] & OP_ADDR_Y) + { + fprintf(output, ", Y"); + } + fprintf(output, "\n"); } void diff --git a/disas/res/Makefrag.am b/disas/res/Makefrag.am new file mode 100644 index 0000000..56c68fe --- /dev/null +++ b/disas/res/Makefrag.am @@ -0,0 +1,8 @@ +if OS_WINDOWS +RES = windows.$(OBJEXT) +else +RES = +endif + +windows.$(OBJEXT): res/windows.rc + $(WINDRES) $< $@ diff --git a/disas/res/disas.ico b/disas/res/disas.ico new file mode 100644 index 0000000000000000000000000000000000000000..3d5d5eddf6e22586631fffae5686c2340ea994b1 GIT binary patch literal 1662 zcmds1F>b;@5L`@TrOaU|ayl>+l-Or~AU?`ewyP9zh2RBgL6HJYBBkUDyn+Wr$`_J1 zk5YjA~eq_1O!qd-L0IT^LH@rh4eA=sS2w3kxHN# zquo{B$$V5uoUGa(AtaaZg*57-gHD$DLNxGFHu7cD>-k6i=BGh52mxXaaBcvWd5CyOA&RwN14!x7Up@-ueEVIrjS7z--!$CtepAQ=0!? teC)ozXu0!SY9IY4UmM?B_N{XIaroac=L_P#TlQr?4*laX&;2{c{{UL+BE$dy literal 0 HcmV?d00001 diff --git a/disas/res/disas.png b/disas/res/disas.png new file mode 100644 index 0000000000000000000000000000000000000000..9454e1af5b75d5673a89ce1d273bc173eb7c1073 GIT binary patch literal 1114 zcmV-g1f~0lP)EX>4Tx04R}tkv&MmKpe$iQ>7wR2RmqS$WWc^q9Tr^ibb$c+6t{Ym|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfc5qU3krMxx6k5c1aNLh~_a1le0HIlBs@W3*RLwHd ziMW`{uZn?J2pGj6M1&<~>dDMv7M|nl9zMR_MR}I@xj)B%QZO0d6NzI?H!R`};@M40 z=e$oGVr5AoJ|~_u=z_$LT$f#b<6LrB;F%#Ko1P~Q5sRfRmb;jh4V8F?IHIT;ZQ$a%qse=~K2d-P^xs+Wq|iwJ~zRj)!l+00006VoOIv0RI600RN!9r;`8x010qNS#tmY zE&KogE&Ktl!|a#<000McNliru=mHrJ5igQPAx;1Q02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00J^eL_t(&-tAbsPQx%1J*n~$jsycMYc@Uskl3$ZUE#v(_Gk~lZgIrhCLHwGFsXwaa+ ze@0|3I_+)|3hB$qc!oPV?QRho02BZab=uuxe0_oGbQ)CZ+}}Llaxz9t2e01WYD4h$ z_{8}v&-3cKRp(jmw7cw?q7^`~emhglq|o8UW^KqHk~Eoz*e;9^uy?S_3wU~d3{F4` zfrAyGl!8(!TmiwaKuCzW!6ZqV6!%Y!-;sw zGHd}D`bweRlH^Ss6>?|2la@}D_^tuDWNI1b={wpBST$73W^VL@SZ_s~&RK+{qZ?nkBRO$aFd+ZvBR&{XXf7%O~Z@{n) zHfm;5{xQazfFmFp5j!nYAyNyPHyT67Xv%oSu&gsmVh9uov008N_ug6rxJ21IQHmj3 g>s^U3c4Ak6PdyEpN{E_*V*mgE07*qoM6N<$g0uAV8vp> 3) & 0x03) +# define IS_TARGET_ZEXT(x) ((x) & TARGET_ZEXT) + + extern const uint8_t opcode_addr[]; extern const char *opcode_str[]; diff --git a/vm/Makefile.am b/vm/Makefile.am index 4568631..cb2a849 100644 --- a/vm/Makefile.am +++ b/vm/Makefile.am @@ -1,5 +1,11 @@ +include jit/Makefrag.am +include ata/Makefrag.am +include res/Makefrag.am + +noinst_LIBRARIES = $(LIBJIT) $(LIB_ATA) + bin_PROGRAMS = vm -vm_SOURCES = main.c jit.c x64/x64.S +vm_SOURCES = main.c vm_CFLAGS =-I$(top_srcdir) -vm_LDADD = ../lib/lib65oo2.a +vm_LDADD = ../lib/lib65oo2.a $(LIBJIT) $(LIB_ATA) $(RES) diff --git a/vm/ata/Makefrag.am b/vm/ata/Makefrag.am new file mode 100644 index 0000000..b4f3817 --- /dev/null +++ b/vm/ata/Makefrag.am @@ -0,0 +1,7 @@ +LIB_ATA = libata.a + +libata_a_SOURCES = ata/ata.c ata/rtc.c + +if USE_ATA_VGA +libata_a_SOURCES += ata/vga.c +endif diff --git a/vm/ata/ata.c b/vm/ata/ata.c new file mode 100644 index 0000000..a0a9b1a --- /dev/null +++ b/vm/ata/ata.c @@ -0,0 +1,27 @@ +#include "ata.h" +#include "config.h" + +extern AtaDevice rtc_dev; +#ifdef ATA_ETHERNET +extern AtaDevice ethernet_dev; +#endif /* ATA_ETHERNET */ +#ifdef ATA_VGA +extern AtaDevice vga_dev; +#endif /* ATA_VGA */ + + +AtaDevice *devices[] = { + &rtc_dev, +#ifdef ATA_ETHERNET + ðernet_dev, +#endif /* ATA_ETHERNET */ +#ifdef ATA_VGA + &vga_dev, +#endif /* ATA_VGA */ + NULL +}; + +void +ata_bus_initialize(void) +{ +} diff --git a/vm/ata/ata.h b/vm/ata/ata.h new file mode 100644 index 0000000..4858c94 --- /dev/null +++ b/vm/ata/ata.h @@ -0,0 +1,19 @@ +#ifndef VM_ATA_ATA_H +# define VM_ATA_ATA_H 1 + +# include + +typedef void (*IoWrite)(uint8_t offset, uint8_t data); +typedef uint8_t (*IoRead)(uint8_t offset); + +typedef struct +{ + char const *name; + uint16_t start; + uint16_t end; + void *state; + IoWrite io_write; + IoRead io_read; +} AtaDevice; + +#endif /* VM_ATA_ATA_H */ diff --git a/vm/ata/ethernet.c b/vm/ata/ethernet.c new file mode 100644 index 0000000..233a1bd --- /dev/null +++ b/vm/ata/ethernet.c @@ -0,0 +1,14 @@ +#include "isa.h" + +static const uint8_t mac_addr[6] = { + 0x53, 0x54, 0x41, 0x4C, 0x49, 0x4E +}; + +AtaDevice ethernet_dev = { + "TinyEthernet", + 0x360, + 0x36F, + NULL, + NULL, + NULL +}; diff --git a/vm/ata/rtc.c b/vm/ata/rtc.c new file mode 100644 index 0000000..c88747c --- /dev/null +++ b/vm/ata/rtc.c @@ -0,0 +1,45 @@ +#include +#include "ata.h" + +#define REG_SECS 0x00 +#define REG_MINS 0x00 +#define REG_HOURS 0x00 +#define REG_WKDAY 0x06 +#define REG_DAY 0x07 +#define REG_YEAR 0x09 +#define REG_CENTURY 0x032 +#define REG_STATUSA 0x0A +#define REG_STATUSB 0x0B + +static uint8_t current_reg = 0x00; + +void +rtc_write(uint8_t addr, uint8_t value) +{ + if (addr == 0) + { + current_reg = value; + } +} + +uint8_t +rtc_read(uint8_t addr) +{ + time_t time; + struct tm tm; + + localtime(&time); + + (void)time; + (void)tm; + + return (0x00); +} + +AtaDevice rtc_dev = { + "RTC", + 0x070, + 0x071, + NULL, + NULL +}; diff --git a/vm/ata/serial.c b/vm/ata/serial.c new file mode 100644 index 0000000..3bfee6c --- /dev/null +++ b/vm/ata/serial.c @@ -0,0 +1,25 @@ +#include "ata.h" + +AtaDevice com3_dev = { + "COM3", + 0x3E0, + 0x3EF, + NULL, + NULL +}; + +AtaDevice com2_dev = { + "COM2", + 0x2F8, + 0x2FF, + NULL, + NULL, +}; + +AtaDevice com1_dev = { + "COM1", + 0x3F8, + 0x3FF, + NULL, + NULL, +}; diff --git a/vm/ata/vga.c b/vm/ata/vga.c new file mode 100644 index 0000000..258d1af --- /dev/null +++ b/vm/ata/vga.c @@ -0,0 +1,22 @@ +#include "ata.h" + +enum VGA_REG { + REG_CRTC_ADDR, + REG_CRTC_DATA, + REG_INPUT_STATUS1, + REG_FEAT_CTRL, + REG_ATTR_ADDR, + REG_ATTR_DATA, +}; + +enum VGA_CRTC { + XXX +}; + +AtaDevice vga_dev = { + "TinyVGA", + 0x3C0, + 0x3CF, + NULL, + NULL, +}; diff --git a/vm/bus.c b/vm/bus.c new file mode 100644 index 0000000..ce1a0d5 --- /dev/null +++ b/vm/bus.c @@ -0,0 +1,19 @@ +void +bus_initialize(void) +{ +} + +void +bus_read(void) +{ +} + +void +bus_write(void) +{ +} + +void +bus_reset(void) +{ +} diff --git a/vm/jit/Makefrag.am b/vm/jit/Makefrag.am new file mode 100644 index 0000000..98c4d97 --- /dev/null +++ b/vm/jit/Makefrag.am @@ -0,0 +1,7 @@ +if USE_JIT +LIBJIT = libjit.a +else +LIBJIT = +endif + +libjit_a_SOURCES = jit/jit.c jit/x64/x64.S diff --git a/vm/jit.c b/vm/jit/jit.c similarity index 100% rename from vm/jit.c rename to vm/jit/jit.c diff --git a/vm/jit.h b/vm/jit/jit.h similarity index 100% rename from vm/jit.h rename to vm/jit/jit.h diff --git a/vm/x64/register.h b/vm/jit/x64/register.h similarity index 100% rename from vm/x64/register.h rename to vm/jit/x64/register.h diff --git a/vm/x64/x64.S b/vm/jit/x64/x64.S similarity index 100% rename from vm/x64/x64.S rename to vm/jit/x64/x64.S diff --git a/vm/main.c b/vm/main.c index abcb908..26a92f3 100644 --- a/vm/main.c +++ b/vm/main.c @@ -1,8 +1,18 @@ #include #include +static const char *prg_name; + +void +usage(void) +{ + printf("Usage: %s [-hV] [-b bios]\n"); +} + int main(int argc, char **argv) { + prg_name = argv[0]; + return (EXIT_SUCCESS); } diff --git a/vm/res/Makefrag.am b/vm/res/Makefrag.am new file mode 100644 index 0000000..56c68fe --- /dev/null +++ b/vm/res/Makefrag.am @@ -0,0 +1,8 @@ +if OS_WINDOWS +RES = windows.$(OBJEXT) +else +RES = +endif + +windows.$(OBJEXT): res/windows.rc + $(WINDRES) $< $@ diff --git a/vm/res/vm.ico b/vm/res/vm.ico new file mode 100644 index 0000000000000000000000000000000000000000..ee39312e6c8a08aa0907f6fa160df2cb38b4ed88 GIT binary patch literal 3774 zcmeHKy-ve05dNIhZPFypR^<^GJFzfyph65FL8nR`sF?WKkYGf80bu0;7*HMp^-*|} zaBh+&Vu;U3{7CpaIVU+^&UatzlMD#5@fh?B@T!0jfE^k%g(VF=--Rs8aI(LP#cYD} z`4r2=8E!96ad$n#{mmScr#(D89^>fw5C<<)T)kZ&&vO(-(G}Lca|$>GoB~dPP6ea| zD3DYZkdUboY$zjNiN=I5@xxHH%*>DC7D6Lmsl?kNR+O0`|0wZ$6}*@g-w*m5^gL$# zpg+(b5dXX4*ZKUB_(2J-K7I|JK1l=4|5Z_Ak#YYJp=ESR>iv_Zyd(2dd|oz9{&swR z|0(OW?LR{^ss>rcH`9lpgHFchmkWF$e`=r>(97`UlvUZz{hk7JhuK_XZ2h}V*$39z X3t*-FKfp@YNcFC@r}}Mm`^^6UTDp@4 literal 0 HcmV?d00001 diff --git a/vm/res/vm.png b/vm/res/vm.png new file mode 100644 index 0000000000000000000000000000000000000000..a94c78c60be418fcaf3623a68dc2fdf4d6579b55 GIT binary patch literal 1001 zcmVEX>4Tx04R}tkv&MmKpe$iQ>7wR2RmqS$WWc^q9Tr^ibb$c+6t{Ym|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfc5qU3krMxx6k5c1aNLh~_a1le0HIlBs@W3*RLwHd ziMW`{uZn?J2pGj6M1&<~>dDMv7M|nl9zMR_MR}I@xj)B%QZO0d6NzI?H!R`};@M40 z=e$oGVr5AoJ|~_u=z_$LT$f#b<6LrB;F%#Ko1P~Q5sRfRmb;jh4V8F?IHIT;ZQ$a%qse=~K2d-P^xs+Wq|iwJ~zRj)!l+00006VoOIv0RI600RN!9r;`8x010qNS#tmY zE&KogE&Ktl!|a#<000McNliru=mHrJ8U)=A0mT3S02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00F^CL_t(&-tCw%Pr^VH$Nz1>(ZR4ZC?W9+Fz^A4BMc<2 z4YV5LLQ)d_0<4TSI$NSFFd3uKLBdy1VhjT=q8-2(LP!HK*1;4D*4k>2yLi9lUD|8< z-u>_0yE}lvU@#c}8O~}*qHNOQbg`t3`3^~xP1*op0stq8vZ);%pi-$&HFZvp&rmFB z2-qJUw(f~>@ML@E%Xj5+dDP}f9%V_C9jzUnf@J+H`o20fHb*^~b8J`m#hR5X;AXTdVC_2mS(U zM6011qM-