├── demo.lst ├── .gitignore ├── resources ├── test.sub ├── mc.chr ├── demo.raw ├── misc.spr ├── wow.spr ├── burwor.spr ├── default.chr ├── garwor.spr ├── pacman.snd ├── thorwor.spr ├── voice1.pho ├── voice2.pho ├── voice4.pho ├── worluck.spr ├── worrior.spr ├── fonts │ ├── mc.chr │ ├── cyborg_multi.64c │ └── conflict_in_vietnam_multi.64c └── sprites │ ├── wow.d64 │ ├── sprites.d64 │ └── action_replay_6.crt ├── disks ├── boot.d71 ├── demo.d71 ├── talk.d71 ├── graphics.d71 ├── playpcm.d71 └── cpm-plus-v3.1-128-y2k-fixed.d71 ├── images ├── title.png ├── vdccon.png ├── vdckey.png ├── viccon.png ├── vickey.png ├── vicspr.png ├── vdcgraph.png ├── vicgraph.png ├── vicgrmcm.png └── vicsplit.png ├── .settings ├── org.eclipse.core.resources.prefs └── org.eclipse.cdt.core.prefs ├── c3l.lst ├── scripts ├── submit.sh ├── fonts.sh ├── sprites.sh └── phonemes.sh ├── src ├── rtc │ ├── get_rtc_mode.c │ ├── get_rtc_reg.c │ └── set_rtc_reg.c ├── vdc │ ├── set_vdc_64k.c │ ├── set_vdc_attrs_on.c │ ├── set_vdc_attrs_off.c │ ├── clear_vdc_bmp.c │ ├── clear_vdc_scr.c │ ├── set_vdc_fg_bg.c │ ├── is_vdc_64k.c │ ├── clear_vdc_scr_col.c │ ├── clear_vdc_bmp_col.c │ ├── done_vdc.c │ ├── set_vdc_cursor.c │ ├── set_vdc_pix.c │ ├── set_vdc_bmp_mode.c │ ├── set_vdc_int_pix.c │ ├── set_vdc_dsp_page.c │ ├── scroll_vdc_up_y.c │ ├── draw_vdc_line_v.c │ ├── scroll_vdc_up_y_col.c │ ├── init_vdc_scr_mode.c │ ├── or_vdc_byte.c │ ├── and_vdc_byte.c │ ├── copy_vdc_to_str.c │ ├── print_vdc_col.c │ ├── print_vdc.c │ ├── copy_vdc_chr_mem.c │ ├── copy_vdc_mem_chr.c │ ├── vdc_in.asm │ ├── init_vdc_bmp_mode.c │ ├── scroll_vdc_up.c │ ├── init_vdc_int_scr_mode.c │ ├── save_vdc.c │ ├── scroll_vdc_up_col.c │ ├── fill_vdc_mem.c │ ├── vdc_out.asm │ ├── vdc_chr_mem_to_file.c │ ├── copy_vdc_mem.c │ ├── print_vdc_bmp.c │ ├── print_vdc_bmp_col.c │ ├── init_vdc_int_bmp_mode.c │ ├── init_vdc_scr.c │ ├── init_vdc_int_scr.c │ ├── init_vdc_bmp.c │ ├── init_vdc_int_bmp.c │ └── draw_vdc_line_h.c ├── cia │ ├── done_cia.c │ ├── bcd_to_byte.c │ ├── get_joystick_1.c │ ├── get_joystick_2.c │ ├── get_key_col.c │ ├── get_ls_key_col.c │ ├── get_rs_key_col.c │ ├── start_timer_a.c │ ├── init_cia.c │ ├── set_cia_tod.c │ ├── start_timer_b.c │ ├── start_timer_ab.c │ ├── get_keys.c │ ├── get_key.c │ ├── tod_to_ms.c │ └── decode_key.c ├── vic │ ├── set_vic_bmp_mem.c │ ├── clear_vic_bmp.c │ ├── clear_vic_scr.c │ ├── clear_vic_bmp_col.c │ ├── set_vic_scr_mem.c │ ├── set_vic_chr_mem.c │ ├── print_vic_pet.c │ ├── clear_vic_col.c │ ├── fill_vic_mem.c │ ├── set_vic_pix.c │ ├── enable_vic_spr.c │ ├── disable_vic_spr.c │ ├── set_vic_spr_bg.c │ ├── set_vic_spr_fg.c │ ├── print_vic_col_pet.c │ ├── done_vic.c │ ├── copy_vic_to_str.c │ ├── scroll_vic_up_y.c │ ├── set_vic_chr_mode.c │ ├── print_vic.c │ ├── set_vic_bank.c │ ├── set_vic_mmu_bank.c │ ├── set_vic_mode.c │ ├── scroll_vic_up_y_col.c │ ├── config_vic_spr.c │ ├── print_vic_col.c │ ├── set_vic_bmp_mode.c │ ├── alloc_vic_mem.c │ ├── set_vic_spr_loc.c │ ├── scroll_vic_up.c │ ├── print_vic_bmp.c │ ├── scroll_vic_up_col.c │ ├── set_vic_pix_mc.c │ ├── print_vic_bmp_col.c │ ├── save_vic.c │ ├── draw_vic_line_v.c │ ├── draw_vic_line_vmc.c │ ├── fill_vic_mem_col.asm │ ├── init_vic_bmp_mode.c │ ├── init_vic_scr_mode.c │ ├── init_vic_scr.c │ ├── init_vic_bmp_mode_mc.c │ ├── init_vic_bmp.c │ ├── init_vic_bmp_mc.c │ ├── draw_vic_line_hmc.c │ ├── scroll_vic_up_asm.asm │ ├── draw_vic_line_h.c │ ├── scroll_vic_up_col_asm.asm │ └── vic_split_scr.asm ├── app │ ├── baseline.c │ ├── vdcfile.c │ ├── rtcdemo.c │ ├── vdcdev.c │ ├── vdccon.c │ ├── vdcconi.c │ ├── ciademo.c │ ├── cpmdir.c │ ├── vdcgraph.c │ ├── vicdev.c │ ├── viccon.c │ ├── vicgraph.c │ ├── observer.c │ ├── vdcgrint.c │ ├── dualcon.c │ ├── vicgrmcm.c │ ├── textperf.c │ ├── vicsplit.c │ ├── vdctest.c │ └── siddemo.c ├── sid │ ├── set_sid_rel.c │ ├── clear_sid.c │ ├── set_sid_vol.c │ ├── set_sid_att.c │ ├── set_sid_freq.c │ ├── set_sid_pul_wav.c │ ├── set_sid_env.c │ ├── read_sid_mouse.c │ ├── read_sid_pots.c │ ├── pcm4.asm │ ├── pcm2.asm │ └── pcm1.asm ├── console │ ├── offset_con.c │ ├── init_con.c │ ├── set_cur_con.c │ ├── clear_home_con.c │ ├── print_line_con.c │ ├── print_con.c │ ├── print_wrap_con.c │ ├── scroll_con.c │ └── read_line_con.c ├── common │ ├── free_list.c │ ├── subject_notify.c │ ├── file_to_mem.c │ ├── subject_init.c │ ├── ascii_to_pet.c │ ├── insert_end.c │ ├── create_node.c │ ├── subject_add_observer.c │ ├── subject_remove_observer.c │ ├── get_dir.c │ ├── fcb_to_file_name.c │ └── init_dir.c ├── graphics │ ├── draw_circle.c │ ├── draw_square.c │ ├── draw_rect.c │ ├── draw_bezier.c │ ├── draw_line.c │ └── draw_ellipse.c └── demo │ ├── wait_key.c │ ├── read_line.c │ ├── run_key_demo.c │ ├── generate_sentence.c │ ├── run_con_demo.c │ ├── keyboard.c │ └── run_dual_demo.c ├── .project ├── include ├── rtc.h ├── mmu.h ├── demo.h ├── console.h ├── common.h ├── sid.h ├── screen.h └── cia.h ├── .cproject └── Makefile /demo.lst: -------------------------------------------------------------------------------- 1 | build/demo/* -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /Debug/ 3 | -------------------------------------------------------------------------------- /resources/test.sub: -------------------------------------------------------------------------------- 1 | baseline 2 | baseline 3 | baseline 4 | -------------------------------------------------------------------------------- /disks/boot.d71: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/disks/boot.d71 -------------------------------------------------------------------------------- /disks/demo.d71: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/disks/demo.d71 -------------------------------------------------------------------------------- /disks/talk.d71: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/disks/talk.d71 -------------------------------------------------------------------------------- /images/title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/images/title.png -------------------------------------------------------------------------------- /resources/mc.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/mc.chr -------------------------------------------------------------------------------- /disks/graphics.d71: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/disks/graphics.d71 -------------------------------------------------------------------------------- /disks/playpcm.d71: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/disks/playpcm.d71 -------------------------------------------------------------------------------- /images/vdccon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/images/vdccon.png -------------------------------------------------------------------------------- /images/vdckey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/images/vdckey.png -------------------------------------------------------------------------------- /images/viccon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/images/viccon.png -------------------------------------------------------------------------------- /images/vickey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/images/vickey.png -------------------------------------------------------------------------------- /images/vicspr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/images/vicspr.png -------------------------------------------------------------------------------- /resources/demo.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/demo.raw -------------------------------------------------------------------------------- /resources/misc.spr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/misc.spr -------------------------------------------------------------------------------- /resources/wow.spr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/wow.spr -------------------------------------------------------------------------------- /images/vdcgraph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/images/vdcgraph.png -------------------------------------------------------------------------------- /images/vicgraph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/images/vicgraph.png -------------------------------------------------------------------------------- /images/vicgrmcm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/images/vicgrmcm.png -------------------------------------------------------------------------------- /images/vicsplit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/images/vicsplit.png -------------------------------------------------------------------------------- /resources/burwor.spr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/burwor.spr -------------------------------------------------------------------------------- /resources/default.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/default.chr -------------------------------------------------------------------------------- /resources/garwor.spr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/garwor.spr -------------------------------------------------------------------------------- /resources/pacman.snd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/pacman.snd -------------------------------------------------------------------------------- /resources/thorwor.spr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/thorwor.spr -------------------------------------------------------------------------------- /resources/voice1.pho: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/voice1.pho -------------------------------------------------------------------------------- /resources/voice2.pho: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/voice2.pho -------------------------------------------------------------------------------- /resources/voice4.pho: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/voice4.pho -------------------------------------------------------------------------------- /resources/worluck.spr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/worluck.spr -------------------------------------------------------------------------------- /resources/worrior.spr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/worrior.spr -------------------------------------------------------------------------------- /resources/fonts/mc.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/fonts/mc.chr -------------------------------------------------------------------------------- /resources/sprites/wow.d64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/sprites/wow.d64 -------------------------------------------------------------------------------- /.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding/=UTF-8 3 | -------------------------------------------------------------------------------- /resources/sprites/sprites.d64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/sprites/sprites.d64 -------------------------------------------------------------------------------- /resources/fonts/cyborg_multi.64c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/fonts/cyborg_multi.64c -------------------------------------------------------------------------------- /disks/cpm-plus-v3.1-128-y2k-fixed.d71: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/disks/cpm-plus-v3.1-128-y2k-fixed.d71 -------------------------------------------------------------------------------- /resources/sprites/action_replay_6.crt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/sprites/action_replay_6.crt -------------------------------------------------------------------------------- /resources/fonts/conflict_in_vietnam_multi.64c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sgjava/c3l/HEAD/resources/fonts/conflict_in_vietnam_multi.64c -------------------------------------------------------------------------------- /c3l.lst: -------------------------------------------------------------------------------- 1 | build/cia/* 2 | build/rtc/* 3 | build/sid/* 4 | build/vdc/* 5 | build/vic/* 6 | build/common/* 7 | build/console/* 8 | build/graphics/* -------------------------------------------------------------------------------- /scripts/submit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd ../resources 3 | # Create test submit file 4 | echo "baseline\r" > test.sub 5 | echo "baseline\r" >> test.sub 6 | echo "baseline\r" >> test.sub 7 | -------------------------------------------------------------------------------- /.settings/org.eclipse.cdt.core.prefs: -------------------------------------------------------------------------------- 1 | doxygen/doxygen_new_line_after_brief=true 2 | doxygen/doxygen_use_brief_tag=false 3 | doxygen/doxygen_use_javadoc_tags=true 4 | doxygen/doxygen_use_pre_tag=false 5 | doxygen/doxygen_use_structural_commands=false 6 | eclipse.preferences.version=1 7 | -------------------------------------------------------------------------------- /src/rtc/get_rtc_mode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * DS12C887 - Real Time Clock. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Set RTC mode. 11 | */ 12 | void setRtcMode(const unsigned char mode) { 13 | setRtcReg(rtcMode, mode); 14 | } 15 | -------------------------------------------------------------------------------- /src/vdc/set_vdc_64k.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Set VDC to 64k mode 11 | */ 12 | void setVdc64k() { 13 | outVdc(vdcChSetStAddr, inVdc(vdcChSetStAddr) | 0x10); 14 | } 15 | -------------------------------------------------------------------------------- /src/vdc/set_vdc_attrs_on.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Turn attributes on. 11 | */ 12 | void setVdcAttrsOn() { 13 | outVdc(vdcHzSmScroll, inVdc(vdcHzSmScroll) | 0x40); 14 | } 15 | -------------------------------------------------------------------------------- /src/vdc/set_vdc_attrs_off.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Turn attributes off. 11 | */ 12 | void setVdcAttrsOff() { 13 | outVdc(vdcHzSmScroll, inVdc(vdcHzSmScroll) & 0xbf); 14 | } 15 | -------------------------------------------------------------------------------- /src/cia/done_cia.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6526 CIA functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Enable CIA 1 interrupts. 12 | */ 13 | void doneCia() { 14 | // Enable CIA 1 IRQ 15 | outp(cia1+ciaIcr, ciaEnableIrq); 16 | } 17 | -------------------------------------------------------------------------------- /src/cia/bcd_to_byte.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6526 CIA demo functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Convert BCD byte to base 10 byte. 11 | */ 12 | unsigned char bcdToByte(const unsigned char bcd) { 13 | return ((bcd >> 4) * 10) + (bcd & 0x0f); 14 | } 15 | -------------------------------------------------------------------------------- /src/vic/set_vic_bmp_mem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | void setVicBmpMem(const unsigned char bmpLoc) { 11 | outp(vicMemCtrl, (inp(vicMemCtrl) & 0xf0) | (bmpLoc << 3)); 12 | } 13 | -------------------------------------------------------------------------------- /src/app/baseline.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * Baseline app. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | #pragma output noprotectmsdos 13 | 14 | int main(void) { 15 | 16 | printf("Hello\n"); 17 | return EXIT_SUCCESS; 18 | } 19 | -------------------------------------------------------------------------------- /src/rtc/get_rtc_reg.c: -------------------------------------------------------------------------------- 1 | /* 2 | * DS12C887 - Real Time Clock. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Get RTC register. 12 | */ 13 | unsigned char getRtcReg(const unsigned char reg) { 14 | outp(rtcRegA, reg); 15 | return inp(rtcRegB); 16 | } 17 | -------------------------------------------------------------------------------- /src/sid/set_sid_rel.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6581/8580 SID functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Start release cycle. 12 | */ 13 | void setSidRel(const unsigned int voice, const unsigned char waveform) { 14 | outp(voice + 4, waveform); 15 | } 16 | -------------------------------------------------------------------------------- /src/vdc/clear_vdc_bmp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Clear screen. 12 | */ 13 | void clearVdcBmp(const bitmap *bmp, const unsigned char c) { 14 | fillVdcMem(bmp->bmpMem, bmp->bmpSize, c); 15 | } 16 | -------------------------------------------------------------------------------- /src/vdc/clear_vdc_scr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Clear screen. 12 | */ 13 | void clearVdcScr(const screen *scr, const unsigned char c) { 14 | fillVdcMem(scr->scrMem, scr->scrSize, c); 15 | } 16 | -------------------------------------------------------------------------------- /src/vdc/set_vdc_fg_bg.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Set foreground and background color. 11 | */ 12 | void setVdcFgBg(const unsigned char f, const unsigned char b) { 13 | outVdc(vdcFgBgColor, (f << 4) | (b & 0x0f)); 14 | } 15 | -------------------------------------------------------------------------------- /src/vdc/is_vdc_64k.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Is VDC in 64k mode? 11 | */ 12 | unsigned char isVdc64k() { 13 | if (inVdc(vdcChSetStAddr) & 0x10 == 0x10) { 14 | return 1; 15 | } else { 16 | return 0; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/rtc/set_rtc_reg.c: -------------------------------------------------------------------------------- 1 | /* 2 | * DS12C887 - Real Time Clock. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /** 11 | * Set RTC register. 12 | */ 13 | void setRtcReg(const unsigned char reg, const unsigned char value) { 14 | outp(rtcRegA, reg); 15 | outp(rtcRegB, value); 16 | } 17 | -------------------------------------------------------------------------------- /src/sid/clear_sid.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6581/8580 SID functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Clear all SID registers. 12 | */ 13 | void clearSid() { 14 | unsigned int i; 15 | for (i = sidVoice1; i <= sidEnvGen3; i++) { 16 | outp(i, 0); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/sid/set_sid_vol.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6581/8580 SID functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Set master volume and filter select. 12 | */ 13 | void setSidVol(const unsigned char amp, const unsigned char filter) { 14 | outp(sidVolume, filter | amp); 15 | } 16 | -------------------------------------------------------------------------------- /src/console/offset_con.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M console calculate offset. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Calculate offset in screen memory based on cursor position. 11 | */ 12 | unsigned int offsetCon(const console *con) { 13 | return con->curY * con->scr->scrWidth + con->curX; 14 | } 15 | -------------------------------------------------------------------------------- /src/vdc/clear_vdc_scr_col.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Clear screen color. 12 | */ 13 | void clearVdcScrCol(const screen *scr, const unsigned char c) { 14 | fillVdcMem(scr->scrColMem, scr->scrSize, scr->color[c]); 15 | } 16 | -------------------------------------------------------------------------------- /src/vic/clear_vic_bmp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Clear screen unsigned char. 12 | */ 13 | void clearVicBmp(const bitmap *bmp, const unsigned char c) { 14 | fillVicMem(bmp->bmpMem, bmp->bmpSize, c); 15 | } 16 | -------------------------------------------------------------------------------- /src/cia/get_joystick_1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6526 CIA functions. 3 | * 4 | * Read joystick 1. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | * Read joystick 1. Assuming CIA 1 DDR B is set to 0x00. 14 | */ 15 | unsigned char getJoystick1() { 16 | return inp(cia1+ciaDataB) & ciaNone; 17 | } 18 | -------------------------------------------------------------------------------- /src/cia/get_joystick_2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6526 CIA functions. 3 | * 4 | * Read joystick 2. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | * Read joystick 2. Assuming CIA 1 DDR A is set to 0xff. 14 | */ 15 | unsigned char getJoystick2() { 16 | return inp(cia1+ciaDataA) & ciaNone; 17 | } 18 | -------------------------------------------------------------------------------- /src/vic/clear_vic_scr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Clear screen using 16 bit word. 12 | */ 13 | void clearVicScr(const screen *scr, const unsigned char c) { 14 | fillVicMem(scr->scrMem, scr->scrSize, c); 15 | } 16 | -------------------------------------------------------------------------------- /src/vdc/clear_vdc_bmp_col.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Clear bitmap color memory. 12 | */ 13 | void clearVdcBmpCol(const bitmap *bmp, const unsigned char c) { 14 | fillVdcMem(bmp->bmpColMem, bmp->bmpColSize, bmp->color[c]); 15 | } 16 | -------------------------------------------------------------------------------- /src/vic/clear_vic_bmp_col.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Clear bitmap color memory. 12 | */ 13 | void clearVicBmpCol(const bitmap *bmp, const unsigned char c) { 14 | fillVicMem(bmp->bmpColMem, bmp->bmpColSize, c); 15 | } 16 | -------------------------------------------------------------------------------- /src/sid/set_sid_att.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6581/8580 SID functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Start attack, decay, sustain cycle. Gate bit is not needed. 12 | */ 13 | void setSidAtt(const unsigned int voice, const unsigned char waveform) { 14 | outp(voice + 4, waveform | sidGate); 15 | } 16 | -------------------------------------------------------------------------------- /src/vic/set_vic_scr_mem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Set screen 0-15 memory location (1K per screen). 12 | */ 13 | void setVicScrMem(const unsigned char scrLoc) { 14 | outp(vicMemCtrl, (inp(vicMemCtrl) & 0x0f) | (scrLoc << 4)); 15 | } 16 | -------------------------------------------------------------------------------- /src/sid/set_sid_freq.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6581/8580 SID functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Set voice frequency. 12 | */ 13 | void setSidFreq(const unsigned int voice, const unsigned int freq) { 14 | outp(voice, (unsigned char ) freq); 15 | outp(voice + 1, (unsigned char ) (freq >> 8)); 16 | } 17 | -------------------------------------------------------------------------------- /src/vdc/done_vdc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Restore VDC registers, screen color, screen memory and char set memory location for CP/M return. 12 | */ 13 | void doneVdc() { 14 | restoreVdc(); 15 | /* ADM-3A clear-home cursor */ 16 | putchar(0x1a); 17 | } 18 | -------------------------------------------------------------------------------- /src/vic/set_vic_chr_mem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Set character set 0-7 memory location (2K per character set). 12 | */ 13 | void setVicChrMem(const unsigned char chrLoc) { 14 | outp(vicMemCtrl, (inp(vicMemCtrl) & 0xf0) | (chrLoc << 1)); 15 | } 16 | -------------------------------------------------------------------------------- /src/sid/set_sid_pul_wav.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6581/8580 SID functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Set pulse waveform width. 12 | */ 13 | void setSidPulWav(const unsigned int voice, const unsigned int width) { 14 | outp(voice + 2, (unsigned char ) width); 15 | outp(voice + 3, (unsigned char ) (width >> 8)); 16 | } 17 | -------------------------------------------------------------------------------- /src/vic/print_vic_pet.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Print PETSCII without color. 12 | */ 13 | void printVicPet(const screen *scr, const unsigned char x, const unsigned char y, const char *str) { 14 | asciiToPet(str); 15 | printVic(scr, x, y, str); 16 | } 17 | -------------------------------------------------------------------------------- /src/console/init_con.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M console. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Initialize console. 11 | */ 12 | void initCon(const console *con, const screen *scr) { 13 | con->curOn = 0; 14 | con->curX = 0; 15 | con->curY = 0; 16 | con->scr = scr; 17 | con->curChar = '_'; 18 | con->colorOn = 0; 19 | con->color = scrWhite; 20 | } 21 | -------------------------------------------------------------------------------- /src/console/set_cur_con.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M console calculate offset. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Set cursor position based on screen offset. 11 | */ 12 | void setCurCon(const console *con, const unsigned int offset) { 13 | con->curY = offset / con->scr->scrWidth; 14 | con->curX = offset - (con->curY * con->scr->scrWidth); 15 | } 16 | -------------------------------------------------------------------------------- /src/vic/clear_vic_col.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Clear color memory. Color memory is port mapped. 12 | */ 13 | void clearVicCol(const screen *scr, const unsigned char c) { 14 | fillVicMemCol((unsigned int) scr->scrColMem, scr->scrSize, scr->color[c]); 15 | } 16 | -------------------------------------------------------------------------------- /src/vic/fill_vic_mem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe general functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Fill memory with unsigned char value. 11 | */ 12 | void fillVicMem(const unsigned char *mem, const unsigned int len, const unsigned char value) { 13 | unsigned int i; 14 | for (i = 0; i < len; i++) { 15 | mem[i] = value; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/vdc/set_vdc_cursor.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Set cursor's top and bottom scan lines and mode. 11 | */ 12 | void setVdcCursor(const unsigned char top, const unsigned char bottom, const unsigned char mode) { 13 | outVdc(vdcCurStScanLine, (top | (mode << 5))); 14 | outVdc(vdcCurEndScanLine, bottom); 15 | } 16 | -------------------------------------------------------------------------------- /src/vdc/set_vdc_pix.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Set pixel. 12 | */ 13 | void setVdcPix(const bitmap *bmp, const unsigned int x, const unsigned int y, const unsigned char color) { 14 | /* Call assembler code */ 15 | setVdcPixAsm(x, y, bmp->color[color], (unsigned int) bmp->bmpMem); 16 | } 17 | -------------------------------------------------------------------------------- /src/common/free_list.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * Common code. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | * Free memory allocated for the list. 14 | */ 15 | void freeList(const node *head) { 16 | while (head != NULL) { 17 | node *temp = head; 18 | head = head->next; 19 | free(temp->data); 20 | free(temp); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/vdc/set_vdc_bmp_mode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Set bitmap memory location, attribute memory location and bitmap mode. 11 | */ 12 | void setVdcBmpMode(const unsigned int dispPage, const unsigned int attrPage) { 13 | setVdcDspPage(dispPage, attrPage); 14 | outVdc(vdcHzSmScroll, inVdc(vdcHzSmScroll) | 0x80); 15 | } 16 | -------------------------------------------------------------------------------- /src/vic/set_vic_pix.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Set pixel. 12 | */ 13 | void setVicPix(const bitmap *bmp, const unsigned int x, const unsigned int y, const unsigned char color) { 14 | /* Call assembler code */ 15 | setVicPixAsm(x, y, bmp->color[color], (unsigned int) bmp->bmpMem); 16 | } 17 | -------------------------------------------------------------------------------- /src/common/subject_notify.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * Common code. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | * Notify all observers of a change. 14 | */ 15 | void subjectNotify(const subject *s) { 16 | for (int i = 0; i < s->count; ++i) { 17 | // Call update on each observer 18 | s->observers[i]->update(s->observers[i]); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/vdc/set_vdc_int_pix.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Set interlace pixel. 12 | */ 13 | void setVdcIntPix(const bitmap *bmp, const unsigned int x, const unsigned int y, const unsigned char color) { 14 | /* Call assembler code */ 15 | setVdcIntPixAsm(x, y, bmp->color[color], (unsigned int) bmp->bmpMem); 16 | } 17 | -------------------------------------------------------------------------------- /src/vic/enable_vic_spr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe sprite functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Enable sprite. 12 | */ 13 | void enableVicSpr(const unsigned char sprNum) { 14 | static unsigned char sprTable[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; 15 | /* Sprite enable */ 16 | outp(vicSprEnable, inp(vicSprEnable) | sprTable[sprNum]); 17 | } 18 | -------------------------------------------------------------------------------- /src/vic/disable_vic_spr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe sprite functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Disable sprite. 12 | */ 13 | void disableVicSpr(const unsigned char sprNum) { 14 | static unsigned char sprTable[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; 15 | /* Sprite disable */ 16 | outp(vicSprEnable, inp(vicSprEnable) & ~sprTable[sprNum]); 17 | } 18 | -------------------------------------------------------------------------------- /src/vic/set_vic_spr_bg.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe sprite functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Make sprite appear in background. 12 | */ 13 | void setVicSprBg(const unsigned char sprNum) { 14 | static unsigned char sprTable[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; 15 | /* Sprite priority */ 16 | outp(vicSprFg, inp(vicSprFg) | sprTable[sprNum]); 17 | } 18 | -------------------------------------------------------------------------------- /src/vic/set_vic_spr_fg.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe sprite functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Make sprite appear in foreground. 12 | */ 13 | void setVicSprFg(const unsigned char sprNum) { 14 | static unsigned char sprTable[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; 15 | /* Sprite priority */ 16 | outp(vicSprFg, inp(vicSprFg) & ~sprTable[sprNum]); 17 | } 18 | -------------------------------------------------------------------------------- /src/common/file_to_mem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M text abstraction. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Read binary file into memory. 12 | */ 13 | void fileToMem(const unsigned char *mem, const unsigned int len, const char *fileName) { 14 | FILE *file; 15 | if ((file = fopen(fileName, "rb")) != NULL) { 16 | fread(mem, sizeof(unsigned char), len, file); 17 | fclose(file); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/vic/print_vic_col_pet.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * Print PETSCII with color. 13 | */ 14 | void printVicColPet(const screen *scr, const unsigned char x, const unsigned char y, const unsigned char color, const char *str) { 15 | asciiToPet(str); 16 | printVicCol(scr, x, y, scr->color[color], str); 17 | } 18 | -------------------------------------------------------------------------------- /src/vic/done_vic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Restore screen color, set MMU bank, VIC bank, screen 12 | * memory and char set memory location for CP/M return. 13 | */ 14 | void doneVic() { 15 | restoreVic(); 16 | /* CPM default */ 17 | setVicMmuBank(0); 18 | setVicBank(0); 19 | /* ADM-3A clear-home cursor */ 20 | putchar(0x1a); 21 | } 22 | -------------------------------------------------------------------------------- /src/common/subject_init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * Common code. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | * Initialize the subject. 14 | */ 15 | void subjectInit(const subject *s) { 16 | // No observers initially 17 | s->count = 0; 18 | // Set initial capacity 19 | s->capacity = 4; 20 | // Allocate memory 21 | s->observers = (observer**) malloc(s->capacity * sizeof(observer*)); 22 | } 23 | -------------------------------------------------------------------------------- /src/vic/copy_vic_to_str.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC general functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Copy VDC memory to C string. 12 | */ 13 | void copyVicToStr(const screen *scr, const unsigned int offset, const char *str, const unsigned int len) { 14 | unsigned int i; 15 | for (i = 0; i < len; i++) { 16 | str[i] = scr->scrMem[i + offset]; 17 | } 18 | /* C style string */ 19 | str[len] = 0x00; 20 | } 21 | -------------------------------------------------------------------------------- /src/vic/scroll_vic_up_y.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Scroll line up given y1 and y2 lines. 12 | */ 13 | void scrollVicUpY(const screen *scr, const unsigned char y1, const unsigned char y2) { 14 | unsigned int scrOfs = y1 * scr->scrWidth + (unsigned int) scr->scrMem; 15 | unsigned char lines = y2 - y1; 16 | scrollVicUpAsm(scrOfs, scr->scrWidth, lines); 17 | } 18 | -------------------------------------------------------------------------------- /src/common/ascii_to_pet.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M text abstraction. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | /* 13 | * Convert string from ASCII to PETSCII. 14 | */ 15 | void asciiToPet(const char *str) { 16 | unsigned int len = strlen(str); 17 | unsigned int i; 18 | for (i = 0; i < len; i++) { 19 | if ((str[i] > 96) && (str[i] <= 127)) { 20 | str[i] = str[i] - 96; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/graphics/draw_circle.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M bitmap circle abstraction. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Draw circle using ellipse with aspect ratio adjustment. 11 | */ 12 | void drawCircle(const bitmap *bmp, const int xc, const int yc, const int a, const unsigned char color) { 13 | /* Circle approximation based on aspect ratio */ 14 | int b = ((a * bmp->aspectRatioMul) / bmp->aspectRatioDiv); 15 | drawEllipse(bmp, xc, yc, a, b, color); 16 | } 17 | -------------------------------------------------------------------------------- /src/sid/set_sid_env.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6581/8580 SID functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Set ADSR envelope. All ADSR values must be >= 0 and <= 15. 12 | */ 13 | void setSidEnv(const unsigned int voice, const unsigned char attack, const unsigned char decay, const unsigned char sustain, 14 | const unsigned char release) { 15 | outp(voice + 5, (attack << 4) | decay); 16 | outp(voice + 6, (sustain << 4) | release); 17 | } 18 | -------------------------------------------------------------------------------- /src/vic/set_vic_chr_mode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Set standard character mode (no MCM or ECM). 11 | */ 12 | void setVicChrMode(const unsigned char mmuRcr, const unsigned char vicBank, const unsigned char scrLoc, const unsigned char chrLoc) { 13 | setVicMmuBank(mmuRcr); 14 | setVicBank(vicBank); 15 | setVicMode(0, 0, 0); 16 | setVicScrMem(scrLoc); 17 | setVicChrMem(chrLoc); 18 | } 19 | -------------------------------------------------------------------------------- /src/console/clear_home_con.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M console clear screen. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Clear screen, color and home cursor. 12 | */ 13 | void clearHomeCon(const console *con) { 14 | /* Clear screen to spaces */ 15 | (con->scr->clearScr)(con->scr, 32); 16 | /* Clear color to white */ 17 | (con->scr->clearScrCol)(con->scr, scrWhite); 18 | /* Home console cursor */ 19 | con->curX = 0; 20 | con->curY = 0; 21 | } 22 | -------------------------------------------------------------------------------- /src/graphics/draw_square.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M bitmap square abstraction. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Draw square using rectangle with aspect ratio adjustment. 11 | */ 12 | void drawSquare(const bitmap *bmp, const int x, const int y, const int len, const unsigned char color) { 13 | /* Square approximation based on aspect ratio */ 14 | int yLen = ((len * bmp->aspectRatioMul) / bmp->aspectRatioDiv); 15 | drawRect(bmp, x, y, len - 1, yLen - 1, color); 16 | } 17 | -------------------------------------------------------------------------------- /src/demo/wait_key.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M wait for return to be pressed. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * Wait for Return key to be pressed. 13 | */ 14 | void waitKey(const screen *scr) { 15 | (scr->printCol)(scr, 0, scr->scrHeight - 1, scrYellow, "Press Return"); 16 | /* Debounce */ 17 | while (getKey(0) == 0xfd) 18 | ; 19 | while (getKey(0) != 0xfd) 20 | ; 21 | /* Debounce */ 22 | while (getKey(0) == 0xfd) 23 | ; 24 | } 25 | -------------------------------------------------------------------------------- /src/cia/get_key_col.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6526 CIA functions. 3 | * 4 | * Keys are mapped the same as getch for the most part. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | 11 | /* 12 | * Get key column. If column not found then 8 is returned. 13 | */ 14 | unsigned char getKeyCol(const unsigned char keyVal) { 15 | static unsigned char keyCol[8] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f }; 16 | unsigned char i = 0; 17 | while ((i < 8) && (keyCol[i] != keyVal)) { 18 | i++; 19 | } 20 | return i; 21 | } 22 | -------------------------------------------------------------------------------- /src/vdc/set_vdc_dsp_page.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Sets which display and attribute page is showing. 11 | */ 12 | void setVdcDspPage(const unsigned int dispPage, const unsigned int attrPage) { 13 | outVdc(vdcDspStAddrHi, (unsigned char) (dispPage >> 8)); 14 | outVdc(vdcDspStAddrLo, (unsigned char) dispPage); 15 | outVdc(vdcAttrStAddrHi, (unsigned char) (attrPage >> 8)); 16 | outVdc(vdcAttrStAddrLo, (unsigned char) attrPage); 17 | } 18 | -------------------------------------------------------------------------------- /src/vdc/scroll_vdc_up_y.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Scroll line up given y1 and y2 lines in current page. 12 | * copyVdcMem the entire block for speed. 13 | */ 14 | void scrollVdcUpY(const screen *scr, const unsigned char y1, const unsigned char y2) { 15 | unsigned int dispOfs = (y1 * scr->scrWidth) + (unsigned int) scr->scrMem; 16 | copyVdcMem(dispOfs, dispOfs - scr->scrWidth, (y2 - y1 + 1) * scr->scrWidth); 17 | } 18 | -------------------------------------------------------------------------------- /src/vic/print_vic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * Print without color. 13 | */ 14 | void printVic(const screen *scr, const unsigned char x, const unsigned char y, const char *str) { 15 | unsigned int scrOfs = (y * scr->scrWidth) + x; 16 | unsigned int len = strlen(str); 17 | unsigned int i; 18 | for (i = 0; i < len; i++) { 19 | scr->scrMem[scrOfs + i] = str[i]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/vdc/draw_vdc_line_v.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Optimized vertical line algorithm uses less calculation and flow control than drawLine. 12 | */ 13 | void drawVdcLineV(const bitmap *bmp, const unsigned int x, const unsigned int y, const unsigned int len, const unsigned char color) { 14 | unsigned char i, end = y + len; 15 | /* Plot pixels */ 16 | for (i = y; i < end; i++) { 17 | setVdcPix(bmp, x, i, color); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | c3l 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.core.cBuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | 16 | org.eclipse.cdt.core.cnature 17 | org.eclipse.cdt.core.ccnature 18 | org.eclipse.cdt.make.core.makeNature 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/cia/get_ls_key_col.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6526 CIA functions. 3 | * 4 | * Keys are mapped the same as getch for the most part. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | 11 | /* 12 | * Get left shift key column. If column not found then 8 is returned. 13 | */ 14 | unsigned char getLsKeyCol(const unsigned char keyVal) { 15 | static unsigned char lsKeyCol[8] = { 0x7e, 0x7d, 0x7b, 0x77, 0x6f, 0x5f, 0x3f, 0x7f }; 16 | unsigned char i = 0; 17 | while ((i < 8) && (lsKeyCol[i] != keyVal)) { 18 | i++; 19 | } 20 | return i; 21 | } 22 | -------------------------------------------------------------------------------- /src/cia/get_rs_key_col.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6526 CIA functions. 3 | * 4 | * Keys are mapped the same as getch for the most part. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | 11 | /* 12 | * Get right shift key column. If column not found then 8 is returned. 13 | */ 14 | unsigned char getRsKeyCol(const unsigned char keyVal) { 15 | static unsigned char rsKeyCol[8] = { 0xee, 0xed, 0xeb, 0xe7, 0xdf, 0xcf, 0xaf, 0x6f }; 16 | unsigned char i = 0; 17 | while ((i < 8) && (rsKeyCol[i] != keyVal)) { 18 | i++; 19 | } 20 | return i; 21 | } 22 | -------------------------------------------------------------------------------- /src/app/vdcfile.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * Basline app. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #pragma output noprotectmsdos 15 | 16 | int main(void) { 17 | unsigned char *chr = (unsigned char*) malloc(2048); 18 | printf("Writing VDC character set\n"); 19 | vdcChrMemToFile(0x3000, 256, "default.chr"); 20 | printf("Reading VDC character set\n"); 21 | fileToMem(chr, 2048, "default.chr"); 22 | free(chr); 23 | return EXIT_SUCCESS; 24 | } 25 | -------------------------------------------------------------------------------- /src/common/insert_end.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * Common code. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | * Insert a node at the end of the list. 14 | */ 15 | void insertEnd(const node **head, const char *data) { 16 | node *newNode = createNode(data); 17 | if (*head == NULL) { 18 | *head = newNode; 19 | return; 20 | } 21 | node *temp = *head; 22 | while (temp->next != NULL) { 23 | temp = temp->next; 24 | } 25 | temp->next = newNode; 26 | newNode->prev = temp; 27 | } 28 | -------------------------------------------------------------------------------- /src/vic/set_vic_bank.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe general functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * Set VIC bank to 0 - 3. 13 | */ 14 | void setVicBank(const unsigned char vicBank) { 15 | unsigned char saveDdr = inp(cia2+ciaDdrA); 16 | /* Set DDR port A to write */ 17 | outp(cia2+ciaDdrA, inp(cia2+ciaDdrA) | 0x03); 18 | /* Set VIC to bank 0-3 */ 19 | outp(cia2+ciaDataA, (inp(cia2+ciaDataA) & 0xfc) | (3 - vicBank)); 20 | outp(cia2+ciaDdrA, saveDdr); 21 | } 22 | -------------------------------------------------------------------------------- /src/vic/set_vic_mmu_bank.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe general functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * Set VIC to MMU bank 0 or 1. 13 | */ 14 | void setVicMmuBank(const unsigned char mmuRcr) { 15 | // I/O 16 | outp(0x0ff00, 0x7e); 17 | /* If bank 1 then set bit 6 of RCR */ 18 | if (mmuRcr) { 19 | outp(mmuRamCfg, inp(mmuRamCfg) | 0x40); 20 | } else { 21 | outp(mmuRamCfg, inp(mmuRamCfg) & 0xbf); 22 | } 23 | // ROM/RAM 24 | outp(0x0ff00, 0x7f); 25 | } 26 | -------------------------------------------------------------------------------- /src/vic/set_vic_mode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe general functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Set ecm, bmm and mcm to 0 (off) or 1 (on). 12 | */ 13 | void setVicMode(const unsigned char ecm, const unsigned char bmm, const unsigned char mcm) { 14 | /* Set enhanced color and char/bitmap mode */ 15 | outp(vicCtrlReg1, (inp(vicCtrlReg1) & 0x9f) | ((ecm * 0x40) + (bmm * 0x20))); 16 | /* Set multicolor mode */ 17 | outp(vicCtrlReg2, (inp(vicCtrlReg2) & 0xef) | (mcm * 0x10)); 18 | } 19 | -------------------------------------------------------------------------------- /src/common/create_node.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * Common code. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | /* 14 | * Create a new node. Returns NULL on failure. 15 | */ 16 | node* createNode(const char *data) { 17 | node *newNode = (node*) malloc(sizeof(node)); 18 | if (newNode != NULL) { 19 | // Allocate memory for the string and copy data 20 | newNode->data = strdup(data); 21 | newNode->prev = NULL; 22 | newNode->next = NULL; 23 | } 24 | return newNode; 25 | } 26 | -------------------------------------------------------------------------------- /src/vdc/scroll_vdc_up_y_col.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Scroll line color up given y1 and y2 lines in current page. 12 | * copyVdcMem the entire block for speed. 13 | */ 14 | void scrollVdcUpYCol(const screen *scr, const unsigned char y1, const unsigned char y2) { 15 | unsigned int colOfs = (y1 * scr->scrWidth) + (unsigned int) scr->scrColMem; 16 | scrollVdcUpY(scr, y1, y2); 17 | copyVdcMem(colOfs, colOfs - scr->scrWidth, (y2 - y1 + 1) * scr->scrWidth); 18 | } 19 | -------------------------------------------------------------------------------- /src/vdc/init_vdc_scr_mode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Configure for VDC mode and clear screen. 12 | */ 13 | void initVdcScrMode(const screen *scr, const unsigned char bgCol, const unsigned char fgCol, const unsigned char chrCol) { 14 | saveVdc(); 15 | setVdcCursor(0, 0, vdcCurNone); 16 | setVdcDspPage(scr->scrMem, scr->scrColMem); 17 | (scr->clearScrCol)(scr, chrCol); 18 | (scr->clearScr)(scr, 32); 19 | setVdcFgBg(scr->color[fgCol], scr->color[bgCol]); 20 | } 21 | -------------------------------------------------------------------------------- /src/cia/start_timer_a.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6526 CIA functions. 3 | * 4 | * Start CIA timer A. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | Start CIA timer A using Hz value and latch for mode. 14 | */ 15 | void startTimerA(const unsigned int cia, const unsigned int hz, const unsigned char latch) { 16 | unsigned int timerA = ciaTimerFreq / hz; 17 | // CIA Timer A lo 18 | outp(cia+ciaTimerALo, timerA); 19 | // CIA Timer A hi 20 | outp(cia+ciaTimerAHi, (timerA >> 8)); 21 | // Start CIA Timer A 22 | outp(cia+ciaCtrlRegA, latch); 23 | } 24 | -------------------------------------------------------------------------------- /src/vdc/or_vdc_byte.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC general functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Or VDC byte with value and store it. 11 | */ 12 | void orVdcByte(const unsigned int vdcMem, const unsigned char value) { 13 | unsigned char saveByte; 14 | outVdc(vdcUpdAddrHi, (unsigned char) (vdcMem >> 8)); 15 | outVdc(vdcUpdAddrLo, (unsigned char) vdcMem); 16 | saveByte = inVdc(vdcCPUData); 17 | outVdc(vdcUpdAddrHi, (unsigned char) (vdcMem >> 8)); 18 | outVdc(vdcUpdAddrLo, (unsigned char) vdcMem); 19 | outVdc(vdcCPUData, saveByte | value); 20 | } 21 | -------------------------------------------------------------------------------- /src/vdc/and_vdc_byte.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC general functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * And VDC byte with value and store it. 11 | */ 12 | void andVdcByte(const unsigned int vdcMem, const unsigned char value) { 13 | unsigned char saveByte; 14 | outVdc(vdcUpdAddrHi, (unsigned char) (vdcMem >> 8)); 15 | outVdc(vdcUpdAddrLo, (unsigned char) vdcMem); 16 | saveByte = inVdc(vdcCPUData); 17 | outVdc(vdcUpdAddrHi, (unsigned char) (vdcMem >> 8)); 18 | outVdc(vdcUpdAddrLo, (unsigned char) vdcMem); 19 | outVdc(vdcCPUData, saveByte & value); 20 | } 21 | -------------------------------------------------------------------------------- /src/app/rtcdemo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * DS12C887 - Real Time Clock demo. 5 | * 6 | * See https://github.com/ytmytm/c64-ds12c887 7 | * 8 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 9 | */ 10 | 11 | #pragma output noprotectmsdos 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | main() { 18 | printf("\nDefault mode Binary, 24h, DST\n"); 19 | setRtcMode(rtcDefaultMode); 20 | printf("Date %02u/%02u/20%02u, Time: %02u:%02u:%02u\n", getRtcReg(rtcMonth), getRtcReg(rtcDay), getRtcReg(rtcYear), 21 | getRtcReg(rtcHours), getRtcReg(rtcMinutes), getRtcReg(rtcSeconds)); 22 | } 23 | -------------------------------------------------------------------------------- /src/vdc/copy_vdc_to_str.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC general functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Copy VDC memory to C string. 12 | */ 13 | void copyVdcToStr(const screen *scr, const unsigned int offest, const char *str, const unsigned int len) { 14 | unsigned int vdcOfs = (unsigned int) scr->scrMem + offest, i; 15 | outVdc(vdcUpdAddrHi, (char) (vdcOfs >> 8)); 16 | outVdc(vdcUpdAddrLo, (char) vdcOfs); 17 | for (i = 0; i < len; i++) { 18 | str[i] = inVdc(vdcCPUData); 19 | } 20 | /* C style string */ 21 | str[len] = 0x00; 22 | } 23 | -------------------------------------------------------------------------------- /src/vic/scroll_vic_up_y_col.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Scroll line color up given y1 and y2 lines in current page. 12 | */ 13 | void scrollVicUpYCol(const screen *scr, const unsigned char y1, const unsigned char y2) { 14 | /* This is the destination color address */ 15 | unsigned int colOfs = y1 * scr->scrWidth + (unsigned int) scr->scrColMem; 16 | unsigned char lines = y2 - y1; 17 | scrollVicUpY(scr, y1, y2); 18 | scrollVicUpColAsm(colOfs, scr->scrWidth, lines); 19 | } 20 | -------------------------------------------------------------------------------- /src/vdc/print_vdc_col.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * Print with color. 13 | */ 14 | void printVdcCol(const screen *scr, const unsigned char x, const unsigned char y, const unsigned char color, const char *str) { 15 | unsigned int len = strlen(str); 16 | /* No need to print empty string */ 17 | if (len > 0) { 18 | fillVdcMem((unsigned char*) (y * scr->scrWidth) + (unsigned int) scr->scrColMem + x, len, scr->color[color]); 19 | printVdc(scr, x, y, str); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/graphics/draw_rect.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M bitmap rectangle abstraction. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Draw rectangle using line drawing. 11 | */ 12 | void drawRect(const bitmap *bmp, const int x, const int y, const int w, const int h, const unsigned char color) { 13 | /* Top */ 14 | drawLine(bmp, x, y, x + w - 1, y, color); 15 | /* Left */ 16 | drawLine(bmp, x, y + 1, x, y + h - 1, color); 17 | /* Right */ 18 | drawLine(bmp, x + w - 1, y + 1, x + w - 1, y + h - 1, color); 19 | /* Bottom */ 20 | drawLine(bmp, x, y + h - 1, x + w - 1, y + h - 1, color); 21 | } 22 | -------------------------------------------------------------------------------- /src/cia/init_cia.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6526 CIA functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Configure CIA to kill interrupts and enable keyboard scan. 12 | */ 13 | void initCia() { 14 | // Clear all CIA 1 IRQ enable bits 15 | outp(cia1+ciaIcr, ciaClearIcr); 16 | // Clear CIA 1 ICR status 17 | inp(cia1+ciaIcr); 18 | // Clear all CIA 2 IRQ enable bits 19 | outp(cia2+ciaIcr, ciaClearIcr); 20 | // Clear CIA 2 ICR status 21 | inp(cia2+ciaIcr); 22 | // Set CIA 1 DDRs for keyboard scan 23 | outp(cia1+ciaDdrA, 0xff); 24 | outp(cia1+ciaDdrB, 0x00); 25 | } 26 | -------------------------------------------------------------------------------- /src/common/subject_add_observer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * Common code. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | * Add an observer to the subject. 14 | */ 15 | void subjectAddObserver(const subject *s, const observer *o) { 16 | // If array is full 17 | if (s->count >= s->capacity) { 18 | // Double the capacity 19 | s->capacity *= 2; 20 | // Reallocate memory 21 | s->observers = (observer**) realloc(s->observers, s->capacity * sizeof(observer*)); 22 | } 23 | // Add the new observer 24 | s->observers[s->count++] = o; 25 | } 26 | -------------------------------------------------------------------------------- /src/vic/config_vic_spr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe sprite functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * Configure sprite. 13 | */ 14 | void configVicSpr(const screen *scr, const unsigned char *spr, const unsigned char sprNum, const unsigned char sprCol) { 15 | unsigned char vicBank = (unsigned int) scr->scrMem / 16384; 16 | /* Set sprite memory location */ 17 | scr->scrMem[vicSprMemOfs + sprNum] = ((unsigned int) spr - (vicBank * 16384)) / 64; 18 | /* Sprite color */ 19 | outp(vicSpr0Col + sprNum, sprCol); 20 | } 21 | -------------------------------------------------------------------------------- /src/cia/set_cia_tod.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6526 CIA functions. 3 | * 4 | * Set CIA TOD clock. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | Set CIA 2 TOD clock. 14 | */ 15 | void setCiaTod(const unsigned int cia, const unsigned char hour, const unsigned char min, const unsigned char sec, 16 | const unsigned char tenth) { 17 | // CIA TOD hour 18 | outp(cia+ciaTodHrs, hour); 19 | // CIA TOD minute 20 | outp(cia+ciaTodMin, min); 21 | // CIA TOD second 22 | outp(cia+ciaTodSec, sec); 23 | // CIA TOD tenth second (this starts timer) 24 | outp(cia+ciaTodTen, tenth); 25 | } 26 | -------------------------------------------------------------------------------- /src/cia/start_timer_b.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6526 CIA functions. 3 | * 4 | * Start CIA timer B. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | Start CIA timer B using Hz value and latch for mode. 14 | */ 15 | void startTimerB(const unsigned int cia, const unsigned int hz, const unsigned char latch) { 16 | unsigned int timerB = ciaTimerFreq / hz; 17 | // CIA Timer B lo 18 | outp(cia+ciaTimerBLo, (unsigned char ) timerB); 19 | // CIA Timer B hi 20 | outp(cia+ciaTimerBHi, (unsigned char ) (timerB >> 8)); 21 | // Start CIA Timer B 22 | outp(cia+ciaCtrlRegB, latch); 23 | } 24 | -------------------------------------------------------------------------------- /scripts/fonts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Concatnate sprite files extraxted with action replay 6. 3 | # 4 | # Since fonts are saved off with first two byte as load address we trim that off. 5 | # 6 | 7 | # Save current dir 8 | cwd=$(pwd) 9 | 10 | cd ../resources/fonts 11 | 12 | # Build multicolor font in proper sequence 13 | 14 | # Space thru ? 15 | dd if=conflict_in_vietnam_multi.64c bs=1 skip=2 count=256 > mc.chr 16 | # @ thru _ 17 | dd if=conflict_in_vietnam_multi.64c bs=1 skip=258 count=256 >> mc.chr 18 | # ` thru DEL 19 | dd if=conflict_in_vietnam_multi.64c bs=1 skip=770 count=256 >> mc.chr 20 | 21 | # Copy sprite libraries to resources 22 | cp *.chr ../../resources/. 23 | 24 | cd "$cwd" -------------------------------------------------------------------------------- /src/common/subject_remove_observer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * Common code. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | * Remove an observer from the subject. 14 | */ 15 | void subjectRemoveObserver(const subject *s, const observer *o) { 16 | // Find the observer 17 | for (int i = 0; i < s->count; ++i) { 18 | if (s->observers[i] == o) { 19 | // Shift remaining observers 20 | memmove(&s->observers[i], &s->observers[i + 1], (s->count - i - 1) * sizeof(observer*)); 21 | // Decrease count 22 | s->count--; 23 | break; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/vdc/print_vdc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * Print without color. 13 | */ 14 | void printVdc(const screen *scr, const unsigned char x, const unsigned char y, const char *str) { 15 | unsigned int dispOfs = (y * scr->scrWidth) + (unsigned int) scr->scrMem + x; 16 | unsigned int len = strlen(str); 17 | unsigned int i; 18 | outVdc(vdcUpdAddrHi, (unsigned char) (dispOfs >> 8)); 19 | outVdc(vdcUpdAddrLo, (unsigned char) dispOfs); 20 | for (i = 0; i < len; i++) { 21 | outVdc(vdcCPUData, str[i]); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/vic/print_vic_col.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * Print with color. 13 | */ 14 | void printVicCol(const screen *scr, const unsigned char x, const unsigned char y, const unsigned char color, const char *str) { 15 | unsigned int colOfs = (unsigned int) scr->scrColMem + (y * scr->scrWidth) + x; 16 | unsigned int len = strlen(str); 17 | /* 0 length not allowed for fillVicMemCol */ 18 | if (len > 0) { 19 | fillVicMemCol(colOfs, len, scr->color[color]); 20 | printVic(scr, x, y, str); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/demo/read_line.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M simple line editor using console. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | /* 13 | * Simple screen line editor. 14 | */ 15 | void readLine(const console *con) { 16 | screen *scr = con->scr; 17 | char *str; 18 | clearHomeCon(con); 19 | printLineCon(con, "Type in line and press return:"); 20 | printLineCon(con, ""); 21 | str = readLineCon(con, 255); 22 | printLineCon(con, ""); 23 | printLineCon(con, ""); 24 | printLineCon(con, "You entered:"); 25 | printLineCon(con, ""); 26 | printCon(con, str); 27 | free(str); 28 | waitKey(scr); 29 | } 30 | -------------------------------------------------------------------------------- /src/vic/set_vic_bmp_mode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Set bitmap mode. 11 | */ 12 | void setVicBmpMode(const unsigned char mmuRcr, const unsigned char vicBank, unsigned char scrLoc, unsigned char bmpLoc, 13 | const unsigned char mcm) { 14 | /* 15 | * For some reason this function must be included in the app 16 | * source file instead of the lib or it hangs. It works fine 17 | * in text mode. Also works with HTC compiler. 18 | */ 19 | //setVicMmuBank(mmuRcr); 20 | setVicBank(vicBank); 21 | setVicMode(0, 1, mcm); 22 | setVicScrMem(scrLoc); 23 | setVicBmpMem(bmpLoc); 24 | } 25 | -------------------------------------------------------------------------------- /src/vdc/copy_vdc_chr_mem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC general functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Copy VDC character set to memory. 11 | */ 12 | void copyVdcChrMem(const unsigned char *mem, const unsigned int vdcMem, const unsigned int chars) { 13 | unsigned char c; 14 | unsigned int vdcOfs = vdcMem, memOfs = 0, i; 15 | for (i = 0; i < chars; i++) { 16 | outVdc(vdcUpdAddrHi, (unsigned char) (vdcOfs >> 8)); 17 | outVdc(vdcUpdAddrLo, (unsigned char) vdcOfs); 18 | // Only use 8 bytes of 16 byte character definition 19 | for (c = 0; c < 8; c++) { 20 | mem[memOfs + c] = inVdc(vdcCPUData); 21 | } 22 | memOfs += 8; 23 | vdcOfs += 16; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/vdc/copy_vdc_mem_chr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC general functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Copy character set to VDC memory. 11 | */ 12 | void copyVdcMemChr(const unsigned char *mem, const unsigned int vdcMem, const unsigned int chars) { 13 | unsigned char c; 14 | unsigned int vdcOfs = vdcMem, memOfs = 0, i; 15 | for (i = 0; i < chars; i++) { 16 | outVdc(vdcUpdAddrHi, (unsigned char) (vdcOfs >> 8)); 17 | outVdc(vdcUpdAddrLo, (unsigned char) vdcOfs); 18 | /* Only use 8 bytes of 16 byte character definition */ 19 | for (c = 0; c < 8; c++) { 20 | outVdc(vdcCPUData, mem[memOfs + c]); 21 | } 22 | memOfs += 8; 23 | vdcOfs += 16; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/vic/alloc_vic_mem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe general functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Allocate memory in TPA for VIC to use. maxBank Should be 0 - 2. Bank 3 12 | * should be allocated manually since that's the top bank of memory and 13 | * not all 16K is available. 14 | */ 15 | unsigned char* allocVicMem(const unsigned char maxBank) { 16 | unsigned char bank, *vicMem; 17 | unsigned int gap; 18 | vicMem = (unsigned char*) malloc(1); 19 | bank = (unsigned int) vicMem / 16384; 20 | gap = 16384 - ((unsigned int) vicMem - (bank * 16384)); 21 | realloc(vicMem, ((maxBank - bank) * 16384) + gap); 22 | return vicMem; 23 | } 24 | -------------------------------------------------------------------------------- /src/vic/set_vic_spr_loc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe sprite functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Set sprite location. 12 | */ 13 | void setVicSprLoc(const unsigned char sprNum, const unsigned int x, const unsigned char y) { 14 | static unsigned char sprTable[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; 15 | unsigned int num = sprNum << 1; 16 | /* Set sprite X */ 17 | if (x > 255) { 18 | outp(vicSprXmsb, inp(vicSprXmsb) | sprTable[sprNum]); 19 | outp(vicSpr0X + num, x - 256); 20 | } else { 21 | outp(vicSprXmsb, inp(vicSprXmsb) & ~sprTable[sprNum]); 22 | outp(vicSpr0X + num, x); 23 | } 24 | /* Sprite Y */ 25 | outp(vicSpr0y + num, y); 26 | } 27 | -------------------------------------------------------------------------------- /src/common/get_dir.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * Common code. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | /* 14 | * Retrieve directory entries after initDir called. 15 | */ 16 | int getDir(const struct fcb *fcb, const unsigned char dmaBuf[], const node *head) { 17 | int retVal, dmaOffset; 18 | struct fcb retFcb; 19 | // Prime the pump 20 | retVal = bdos(CPM_FNXT, &fcb); 21 | while (retVal > -1) { 22 | dmaOffset = retVal * 32; 23 | memcpy(&retFcb, &dmaBuf[dmaOffset], sizeof(struct fcb)); 24 | // Add to linked list 25 | insertEnd(&head, fcbToFileName(&retFcb)); 26 | retVal = bdos(CPM_FNXT, &fcb); 27 | } 28 | return retVal; 29 | } 30 | -------------------------------------------------------------------------------- /src/vic/scroll_vic_up.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Scroll line up given x1, y1, x2, y2 rectangle in current page. 12 | */ 13 | void scrollVicUp(const screen *scr, const unsigned char x1, const unsigned char y1, const unsigned char x2, const unsigned char y2) { 14 | /* If line is screen width use optimized */ 15 | if (x2 - x1 + 1 == scr->scrWidth) { 16 | scrollVicUpY(scr, y1, y2); 17 | } else { 18 | unsigned int scrOfs = (y1 * scr->scrWidth) + (unsigned int) scr->scrMem + x1; 19 | unsigned char len = x2 - x1 + 1; 20 | unsigned char lines = y2 - y1; 21 | scrollVicUpAsm(scrOfs, len, lines); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/cia/start_timer_ab.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6526 CIA functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Set CIA count down timers. Timer B counts timer A. 12 | */ 13 | void startTimerAB(const unsigned int cia, const unsigned int timerA, const unsigned int timerB, const unsigned char latch) { 14 | // CIA Timer A lo 15 | outp(cia + ciaTimerALo, (unsigned char ) timerA); 16 | // CIA Timer A hi 17 | outp(cia + ciaTimerAHi, (unsigned char ) (timerA >> 8)); 18 | // CIA Timer B lo 19 | outp(cia + ciaTimerBLo, (unsigned char ) timerB); 20 | // CIA Timer B hi 21 | outp(cia + ciaTimerBHi, (unsigned char ) (timerB >> 8)); 22 | // Link time to count and enable timer 23 | outp(cia + ciaCtrlRegB, latch); 24 | } 25 | -------------------------------------------------------------------------------- /src/vdc/vdc_in.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Copyright (c) Steven P. Goldsmith. All rights reserved. 3 | ; 4 | ; Assembled with HI-TECH C 3.09 (CP/M-80) ZAS. 5 | ; 6 | ; Get VDC register 7 | ; 8 | 9 | SECTION code_clib 10 | PUBLIC inVdc 11 | PUBLIC _inVdc 12 | 13 | ; __z88dk_fastcall used in header 14 | 15 | inVdc: 16 | _inVdc: 17 | ld a,l 18 | ld bc,0d600h ; VDC status port 19 | out (c),a ; Set reg to read 20 | rep1: 21 | in a,(c) ; Repeat 22 | and 80h ; Test bit 7 23 | jr z,rep1 ; Until bit 7 high 24 | inc c ; VDC data register 25 | in l,(c) ; Get data 26 | ld h, 0 ; Set high byte to 0 27 | ret 28 | -------------------------------------------------------------------------------- /src/vdc/init_vdc_bmp_mode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8563 VDC bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Copy fonts to memory, set screen struct for VDC and clear screen. 12 | */ 13 | void initVdcBmpMode(const bitmap *bmp, const unsigned char *chrMem, const unsigned char bgCol, const unsigned char fgCol) { 14 | saveVdc(); 15 | /* Turn off cursor for bitmap mode */ 16 | setVdcCursor(0, 0, vdcCurNone); 17 | /* Copy VDC char sets to mem bufer */ 18 | copyVdcChrMem(chrMem, 0x2000, 512); 19 | /* Set bitmap mode */ 20 | setVdcFgBg(bmp->color[fgCol], bmp->color[bgCol]); 21 | setVdcAttrsOff(); 22 | setVdcBmpMode((unsigned int) bmp->bmpMem, (unsigned int) bmp->bmpColMem); 23 | (bmp->clearBmp)(bmp, 0); 24 | } 25 | -------------------------------------------------------------------------------- /src/vdc/scroll_vdc_up.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Scroll line up given x1, y1, x2, y2 rectangle in current page. 12 | */ 13 | void scrollVdcUp(const screen *scr, const unsigned char x1, const unsigned char y1, const unsigned char x2, const unsigned char y2) { 14 | /* If line is screen width use optimized function */ 15 | if (x2 - x1 + 1 == scr->scrWidth) { 16 | scrollVdcUpY(scr, y1, y2); 17 | } else { 18 | unsigned char len = x2 - x1 + 1; 19 | unsigned int dispOfs = (y1 * scr->scrWidth) + (unsigned int) scr->scrMem + x1; 20 | for (; y1 <= y2; y1++) { 21 | copyVdcMem(dispOfs, dispOfs - scr->scrWidth, len); 22 | dispOfs += scr->scrWidth; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/cia/get_keys.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6526 CIA functions. 3 | * 4 | * Keys are mapped the same as getch for the most part. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | * Get all standard and extended key rows. 14 | */ 15 | void getKeys(const unsigned char *ciaKeyScan) { 16 | static unsigned char keyCol[8] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f }; 17 | unsigned char i; 18 | outp(vicExtKey, 0xff); 19 | // Scan standard keys 20 | for (i = 0; i < 8; i++) { 21 | outp(cia1+ciaDataA, keyCol[i]); 22 | ciaKeyScan[i] = inp(cia1+ciaDataB); 23 | } 24 | outp(cia1+ciaDataA, 0xff); 25 | // Scan extended keys 26 | for (i = 0; i < 3; i++) { 27 | outp(vicExtKey, keyCol[i]); 28 | ciaKeyScan[i + 8] = inp(cia1+ciaDataB); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/sid/read_sid_mouse.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6581/8580 SID functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Read 1351 compatible mouse in port 1 and 2 (values are passed by reference). 11 | */ 12 | void readSidMouse(const unsigned char *x1, const unsigned char *y1, const unsigned char *x2, const unsigned char *y2) { 13 | readSidPots(x1, y1, x2, y2); 14 | // Change value if noise bit 0 15 | if ((*x1 & 0x01) == 0) { 16 | *x1 = (*x1 & 0x7f) >> 1; 17 | } 18 | // Change value if noise bit 19 | if ((*y1 & 0x01) == 0) { 20 | *y1 = (*y1 & 0x7f) >> 1; 21 | } 22 | // Change value if noise bit 0 23 | if ((*x2 & 0x01) == 0) { 24 | *x2 = (*x2 & 0x7f) >> 1; 25 | } 26 | // Change value if noise bit 0 27 | if ((*y2 & 0x01) == 0) { 28 | *y2 = (*y2 & 0x7f) >> 1; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/vic/print_vic_bmp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * Print with foreground/background color. 13 | */ 14 | void printVicBmp(const bitmap *bmp, const unsigned char x, const unsigned char y, const char *str) { 15 | unsigned int *bmp16 = (unsigned int*) bmp->bmpMem; 16 | unsigned int *chr16 = (unsigned int*) bmp->bmpChrMem; 17 | unsigned int bmpOfs = (y * 160) + (x * 4); 18 | unsigned int len = strlen(str); 19 | unsigned int i, chrOfs, destOfs; 20 | unsigned char c; 21 | for (i = 0; i < len; i++) { 22 | chrOfs = str[i] << 2; 23 | destOfs = i << 2; 24 | for (c = 0; c < 4; c++) { 25 | bmp16[bmpOfs + destOfs + c] = chr16[chrOfs + c]; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/vdc/init_vdc_int_scr_mode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Configure for VDC interlace mode and clear screen. 12 | */ 13 | void initVdcIntScrMode(const screen *scr, const unsigned char bgCol, const unsigned char fgCol, const unsigned char chrCol) { 14 | saveVdc(); 15 | setVdcCursor(0, 0, vdcCurNone); 16 | // Set 80x50 interlaced text mode with 8x8 chars 17 | outVdc(vdcHzTotal, 128); 18 | outVdc(vdcVtTotal, 64); 19 | outVdc(vdcVtDisp, 50); 20 | outVdc(vdcVtSyncPos, 58); 21 | outVdc(vdcIlaceMode, 3); 22 | outVdc(vdcChTotalVt, 7); 23 | setVdcDspPage(scr->scrMem, scr->scrColMem); 24 | (scr->clearScrCol)(scr, chrCol); 25 | (scr->clearScr)(scr, 32); 26 | setVdcFgBg(scr->color[fgCol], scr->color[bgCol]); 27 | } 28 | -------------------------------------------------------------------------------- /src/vdc/save_vdc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC general functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * VDC registers to save and restore. 11 | */ 12 | static unsigned char vdcSavedRegs[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 34, 13 | 35, 36 }; 14 | 15 | /* 16 | * Saved registers. 17 | */ 18 | unsigned char vdcRegs[sizeof(vdcSavedRegs) - 1]; 19 | 20 | /* 21 | * Save key VDC registers. 22 | */ 23 | void saveVdc() { 24 | unsigned char i; 25 | for (i = 0; i < sizeof(vdcRegs); i++) { 26 | vdcRegs[i] = inVdc(vdcSavedRegs[i]); 27 | } 28 | } 29 | 30 | /* 31 | * Restore key VDC registers. 32 | */ 33 | void restoreVdc() { 34 | unsigned char i; 35 | for (i = 0; i < sizeof(vdcRegs); i++) { 36 | outVdc(vdcSavedRegs[i], vdcRegs[i]); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/vic/scroll_vic_up_col.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * Scroll color window up given x1, y1, x2, y2 rectangle in current page. 13 | */ 14 | void scrollVicUpCol(const screen *scr, const unsigned char x1, const unsigned char y1, const unsigned char x2, 15 | const unsigned char y2) { 16 | /* If line is screen width use optimized function */ 17 | if (x2 - x1 + 1 == scr->scrWidth) { 18 | scrollVicUpYCol(scr, y1, y2); 19 | } else { 20 | unsigned int colOfs = (y1 * scr->scrWidth) + (unsigned int) scr->scrColMem + x1; 21 | unsigned char len = x2 - x1 + 1; 22 | unsigned char lines = y2 - y1; 23 | scrollVicUp(scr, x1, y1, x2, y2); 24 | scrollVicUpColAsm(colOfs, len, lines); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/cia/get_key.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6526 CIA functions. 3 | * 4 | * Keys are mapped the same as getch for the most part. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | * Get standard or extended key code for single row. 0xff is returned if no key 14 | * pressed. keyRow is 0 - 10. 15 | */ 16 | unsigned char getKey(const unsigned char keyRow) { 17 | static unsigned char keyCol[8] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f }; 18 | unsigned char keyCode; 19 | // Standard keys? 20 | if (keyRow < 8) { 21 | outp(vicExtKey, 0xff); 22 | outp(cia1+ciaDataA, keyCol[keyRow]); 23 | keyCode = inp(cia1+ciaDataB); 24 | } else { 25 | // Extended keys 26 | outp(cia1+ciaDataA, 0xff); 27 | outp(vicExtKey, keyCol[keyRow - 8]); 28 | keyCode = inp(cia1+ciaDataB); 29 | } 30 | return keyCode; 31 | } 32 | -------------------------------------------------------------------------------- /src/vdc/scroll_vdc_up_col.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Scroll color window up given x1, y1, x2, y2 rectangle in current page. 12 | */ 13 | void scrollVdcUpCol(const screen *scr, const unsigned char x1, const unsigned char y1, const unsigned char x2, 14 | const unsigned char y2) { 15 | /* If line is screen width use optimized function */ 16 | if (x2 - x1 + 1 == scr->scrWidth) { 17 | scrollVdcUpYCol(scr, y1, y2); 18 | } else { 19 | unsigned char len = x2 - x1 + 1; 20 | unsigned int colOfs = (y1 * scr->scrWidth) + (unsigned int) scr->scrColMem + x1; 21 | scrollVdcUp(scr, x1, y1, x2, y2); 22 | for (; y1 <= y2; y1++) { 23 | copyVdcMem(colOfs, colOfs - scr->scrWidth, len); 24 | colOfs += scr->scrWidth; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/vdc/fill_vdc_mem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC general functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Fast fill using block writes. 11 | */ 12 | void fillVdcMem(const unsigned char *mem, const unsigned int len, const unsigned char value) { 13 | unsigned char blocks, remain; 14 | unsigned char i; 15 | outVdc(vdcUpdAddrHi, (unsigned char) ((unsigned int) mem >> 8)); 16 | outVdc(vdcUpdAddrLo, (unsigned char) (unsigned int) mem); 17 | outVdc(vdcVtSmScroll, (inVdc(vdcVtSmScroll) & 0x7f)); 18 | outVdc(vdcCPUData, value); 19 | if (len > vdcMaxBlock) { 20 | blocks = len / vdcMaxBlock; 21 | remain = len % vdcMaxBlock; 22 | for (i = 1; i <= blocks; i++) 23 | outVdc(vdcWordCnt, vdcMaxBlock); 24 | if (remain > 1) 25 | outVdc(vdcWordCnt, --remain); 26 | } else if (len > 1) 27 | outVdc(vdcWordCnt, --len); 28 | } 29 | -------------------------------------------------------------------------------- /src/cia/tod_to_ms.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6526 CIA demo functions.. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Convert TOD clock to milliseconds since midnight. 12 | * 13 | * For z88dk this sometimes returns a lesser value when 14 | * doing start and end values, so I need to debug this. 15 | * 16 | */ 17 | unsigned long todToMs(const unsigned int cia) { 18 | // Reading hours first stops updating registers for read 19 | unsigned char hour = inp(cia + ciaTodHrs); 20 | // Bit 7 of hour is used as a flag for AM/PM (1 = PM, 0 = AM) 21 | if (hour & 0x80) { 22 | hour = bcdToByte(hour & 0x7f) + 12; 23 | } else { 24 | hour = bcdToByte(hour); 25 | } 26 | return (hour * 3600000) + (bcdToByte(inp(cia + ciaTodMin)) * 60000) + (bcdToByte(inp(cia + ciaTodSec)) * 1000) 27 | + (bcdToByte(inp(cia + ciaTodTen)) * 100); 28 | } 29 | -------------------------------------------------------------------------------- /src/vic/set_vic_pix_mc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Set multicolor pixel. 12 | */ 13 | void setVicPixMc(const bitmap *bmp, const unsigned int x, const unsigned int y, const unsigned char color) { 14 | // Colors 0-3 pixels 15 | static const unsigned char bitTable[4][4] = { { 0x3f, 0xcf, 0xf3, 0xfc }, { 0x40, 0x10, 0x04, 0x01 }, 16 | { 0x80, 0x20, 0x08, 0x02 }, { 0xc0, 0x30, 0x0c, 0x03 } }; 17 | // Calculate the starting byte position in the bitmap memory 18 | unsigned int pixByte = bmp->scrWidth * (y & 0xf8) + (x << 1 & 0x1f8) + (y & 0x07); 19 | unsigned char vBit = bitTable[color][x & 0x03]; 20 | // Clear the relevant bits and apply the color bit 21 | bmp->bmpMem[pixByte] = (bmp->bmpMem[pixByte] & ~vBit) | (color ? vBit : 0); 22 | } 23 | -------------------------------------------------------------------------------- /src/console/print_line_con.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M console print. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * Print to console and set cursor to next line. 13 | */ 14 | void printLineCon(const console *con, const char *str) { 15 | screen *scr = con->scr; 16 | printCon(con, str); 17 | /* Remove cursor if enabled */ 18 | if (con->curOn) { 19 | (scr->print)(scr, con->curX, con->curY, " "); 20 | } 21 | con->curX = 0; 22 | if (con->curY < scr->scrHeight - 1) { 23 | con->curY++; 24 | } else { 25 | if (con->colorOn) { 26 | (scr->scrollUpCol)(scr, 0, 0, scr->scrWidth - 1, scr->scrHeight - 1); 27 | } else { 28 | (scr->scrollUp)(scr, 0, 0, scr->scrWidth - 1, scr->scrHeight - 1); 29 | } 30 | (scr->fillMem)(scr->scrMem + scr->scrSize - scr->scrWidth, scr->scrWidth, 32); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/vdc/vdc_out.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Copyright (c) Steven P. Goldsmith. All rights reserved. 3 | ; 4 | ; Assembled with HI-TECH C 3.09 (CP/M-80) ZAS. 5 | ; 6 | ; Set VDC register 7 | ; 8 | 9 | SECTION code_clib 10 | PUBLIC outVdc 11 | PUBLIC _outVdc 12 | 13 | outVdc: 14 | _outVdc: 15 | pop hl ; Return address? 16 | pop de ; Data 17 | pop bc ; VDC register to write 18 | push bc 19 | push de 20 | push hl 21 | ld a,c 22 | ld bc,0d600h ; VDC status port 23 | out (c),a ; Set reg to read 24 | rep1: 25 | in a,(c) ; Repeat 26 | and 80h ; Test bit 7 27 | jr z,rep1 ; Until bit 7 high 28 | inc c ; VDC data register 29 | out (c),e ; Set data 30 | ret 31 | -------------------------------------------------------------------------------- /include/rtc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * DS12C887 - Real Time Clock. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #ifndef _RTC_H 8 | #define _RTC_H 9 | 10 | #include 11 | 12 | #define rtcRegA 0xde00 /* Register A address */ 13 | #define rtcRegB 0xde01 /* Register B address */ 14 | #define rtcSeconds 0x0 /* Seconds */ 15 | #define rtcMinutes 0x2 /* Minutes */ 16 | #define rtcHours 0x4 /* Hours */ 17 | #define rtcDay 0x7 /* Day */ 18 | #define rtcMonth 0x8 /* Month */ 19 | #define rtcYear 0x9 /* Year */ 20 | #define rtcMode 0xb /* Mode */ 21 | #define rtcDefaultMode 0x87 /* Binary, 24h, DST */ 22 | 23 | extern void __LIB__ setRtcReg(const unsigned char reg, const unsigned char value); 24 | extern unsigned char __LIB__ getRtcReg(const unsigned char reg); 25 | extern void __LIB__ setRtcMode(const unsigned char mode); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/mmu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8722 MMU. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #ifndef _MMU_H 8 | #define _MMU_H 9 | 10 | #define mmuCtrlReg1 0xd500 /* Configuration register */ 11 | #define mmuPreCfgRegA 0xd501 /* Preconfiguration register A */ 12 | #define mmuPreCfgRegB 0xd502 /* Preconfiguration register B */ 13 | #define mmuPreCfgRegC 0xd503 /* Preconfiguration register C */ 14 | #define mmuPreCfgRegD 0xd504 /* Preconfiguration register D */ 15 | #define mmuModeCfg 0xd505 /* Mode configuration register */ 16 | #define mmuRamCfg 0xd506 /* RAM configuration register */ 17 | #define mmuPage0PagePtr 0xd507 /* Page 0 page pointer */ 18 | #define mmuPage0lkPtr 0xd508 /* Page 0 block pointer */ 19 | #define mmuPage1PagePtr 0xd509 /* Page 1 page pointer */ 20 | #define mmuPage1BlkPtr 0xd50a /* Page 1 block pointer */ 21 | #define mmuVerReg 0xd50b /* MMU version register */ 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/vdc/vdc_chr_mem_to_file.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC general functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Copy VDC character set to memory to a file. 12 | */ 13 | void vdcChrMemToFile(const unsigned int vdcMem, const unsigned int chars, const char *fileName) { 14 | unsigned char c; 15 | unsigned int vdcOfs = vdcMem, i; 16 | unsigned char charBuf[8]; 17 | FILE *file; 18 | if ((file = fopen(fileName, "wb")) != NULL) { 19 | for (i = 0; i < chars; i++) { 20 | outVdc(vdcUpdAddrHi, (unsigned char) (vdcOfs >> 8)); 21 | outVdc(vdcUpdAddrLo, (unsigned char) vdcOfs); 22 | // Only use 8 bytes of 16 byte character definition 23 | for (c = 0; c < 8; c++) { 24 | charBuf[c] = inVdc(vdcCPUData); 25 | } 26 | fwrite(charBuf, sizeof(unsigned char), sizeof(charBuf), file); 27 | vdcOfs += 16; 28 | } 29 | fclose(file); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/demo/run_key_demo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M real time key press decode. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | /* 13 | * Run key scan demo. 14 | */ 15 | void runKeyDemo(const console *con) { 16 | screen *scr = con->scr; 17 | char str[40]; 18 | printWrapCon(con, "Low level key scan of standard and extended keyboard. You can also " 19 | "decode unshifted and shifted characters. CIA 1 interrupts are " 20 | "disabled, so as not to disrupt the key scan. Joysticks and paddles " 21 | "are also decoded."); 22 | printLineCon(con, ""); 23 | printLineCon(con, ""); 24 | printLineCon(con, ""); 25 | sprintf(str, "Chr mem: %04x", scr->chrMem); 26 | printLineCon(con, str); 27 | sprintf(str, "Scr mem: %04x", scr->scrMem); 28 | printLineCon(con, str); 29 | waitKey(scr); 30 | keyboard(scr); 31 | readLine(con); 32 | } 33 | -------------------------------------------------------------------------------- /src/vic/print_vic_bmp_col.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * Print with foreground/background color. 13 | */ 14 | void printVicBmpCol(const bitmap *bmp, const unsigned char x, const unsigned char y, const unsigned char color, const char *str) { 15 | unsigned int *bmp16 = (unsigned int*) bmp->bmpMem; 16 | unsigned int *chr16 = (unsigned int*) bmp->bmpChrMem; 17 | unsigned int bmpOfs = (y * 160) + (x * 4); 18 | unsigned int colOfs = (y * bmp->scrWidth) + x; 19 | unsigned int len = strlen(str); 20 | unsigned int i, chrOfs, destOfs; 21 | unsigned char c; 22 | for (i = 0; i < len; i++) { 23 | chrOfs = str[i] << 2; 24 | destOfs = i << 2; 25 | bmp->bmpColMem[colOfs + i] = color; 26 | for (c = 0; c < 4; c++) { 27 | bmp16[bmpOfs + destOfs + c] = chr16[chrOfs + c]; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/vdc/copy_vdc_mem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC general functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Fast copy using block copy. 11 | */ 12 | void copyVdcMem(const unsigned int source, const unsigned int dest, const unsigned int len) { 13 | unsigned char blocks, remain; 14 | unsigned char i; 15 | outVdc(vdcUpdAddrHi, (unsigned char) (dest >> 8)); 16 | outVdc(vdcUpdAddrLo, (unsigned char) dest); 17 | outVdc(vdcVtSmScroll, (inVdc(vdcVtSmScroll) | 0x80)); 18 | outVdc(vdcBlkCpySrcAddrHi, (unsigned char) (source >> 8)); 19 | outVdc(vdcBlkCpySrcAddrLo, (unsigned char) source); 20 | if (len > vdcMaxBlock) { 21 | blocks = len / vdcMaxBlock; 22 | remain = len % vdcMaxBlock; 23 | for (i = 1; i <= blocks; i++) { 24 | outVdc(vdcWordCnt, vdcMaxBlock); 25 | } 26 | if (remain > 0) { 27 | outVdc(vdcWordCnt, remain); 28 | } 29 | } else if (len > 0) { 30 | outVdc(vdcWordCnt, len); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/graphics/draw_bezier.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M bitmap Bézier curve abstraction. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Bézier curve using Bresenham’s line algorithm. 12 | */ 13 | void drawBezier(const bitmap *bmp, const int x0, const int y0, const int x1, const int y1, const int x2, const int y2, 14 | const unsigned char color) { 15 | int sx = x0 < x2 ? 1 : -1; 16 | int sy = y0 < y2 ? 1 : -1; 17 | int x = x2 - x0; 18 | int y = y2 - y0; 19 | int dx = abs(x); 20 | int dy = abs(y); 21 | int ex = dx << 1; 22 | int ey = dy << 1; 23 | int err = ex - ey; 24 | int cx = x0; 25 | int cy = y0; 26 | int e2; 27 | for (;;) { 28 | (bmp->setPixel)(bmp, cx, cy, color); 29 | if (cx == x2 && cy == y2) { 30 | break; 31 | } 32 | e2 = err << 1; 33 | if (e2 > -ey) { 34 | err -= ey; 35 | cx += sx; 36 | } 37 | if (e2 < ex) { 38 | err += ex; 39 | cy += sy; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/vic/save_vic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe save registers. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * VIC registers to save and restore. 12 | */ 13 | static unsigned char vicSavedRegs[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 21, 22, 23, 24, 25, 26, 27, 14 | 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46 }; 15 | 16 | /* 17 | * Saved registers. 18 | */ 19 | unsigned char vicRegs[sizeof(vicSavedRegs) - 1]; 20 | 21 | /* 22 | * Save key VIC registers. 23 | */ 24 | void saveVic() { 25 | unsigned char i; 26 | for (i = 0; i < sizeof(vicRegs); i++) { 27 | vicRegs[i] = inp(vicSpr0X + vicSavedRegs[i]); 28 | } 29 | } 30 | 31 | /* 32 | * Restore key VIC registers. 33 | */ 34 | void restoreVic() { 35 | unsigned char i; 36 | for (i = 0; i < sizeof(vicRegs); i++) { 37 | outp(vicSpr0X + vicSavedRegs[i], vicRegs[i]); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/vdc/print_vdc_bmp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * Print without color. Optimized by setting VDC address once for each scan line. 13 | */ 14 | void printVdcBmp(const bitmap *bmp, const unsigned char x, const unsigned char y, const char *str) { 15 | unsigned int vdcMem = (unsigned int) bmp->bmpMem; 16 | unsigned int dispOfs = ((y * bmp->scrWidth) * 8) + vdcMem + x; 17 | unsigned int len = strlen(str); 18 | unsigned int i, chrOfs; 19 | unsigned char c; 20 | /* Draw 8 scan lines */ 21 | for (c = 0; c < 8; c++) { 22 | outVdc(vdcUpdAddrHi, (unsigned char) (dispOfs >> 8)); 23 | outVdc(vdcUpdAddrLo, (unsigned char) dispOfs); 24 | for (i = 0; i < len; i++) { 25 | chrOfs = (str[i] << 3) + c; 26 | outVdc(vdcCPUData, bmp->bmpChrMem[chrOfs]); 27 | } 28 | /* Next scan line */ 29 | dispOfs += bmp->scrWidth; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/console/print_con.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M console print. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * Print to console. 13 | */ 14 | void printCon(const console *con, const char *str) { 15 | screen *scr = con->scr; 16 | unsigned int scrOfs; 17 | scrollCon(con, str); 18 | if (con->colorOn) { 19 | (scr->printCol)(scr, con->curX, con->curY, con->color, str); 20 | } else { 21 | (scr->print)(scr, con->curX, con->curY, str); 22 | } 23 | /* Calculate new cursor position */ 24 | scrOfs = offsetCon(con) + strlen(str); 25 | /* Advance cursor */ 26 | setCurCon(con, scrOfs); 27 | /* Display cursor if enabled */ 28 | if (con->curOn) { 29 | char cursor[2]; 30 | cursor[0] = con->curChar; 31 | cursor[1] = 0x00; 32 | if (con->colorOn) { 33 | (scr->printCol)(scr, con->curX, con->curY, con->color, cursor); 34 | } else { 35 | (scr->print)(scr, con->curX, con->curY, cursor); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/vic/draw_vic_line_v.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Optimized vertical line algorithm uses less calculation than setVicPix. 12 | */ 13 | void drawVicLineV(const bitmap *bmp, const unsigned int x, const unsigned int y, const unsigned int len, const unsigned char color) { 14 | static unsigned char bitTable[8] = { 128, 64, 32, 16, 8, 4, 2, 1 }; 15 | unsigned int pixByte = bmp->scrWidth * (y & 0xf8) + (x & 0x1f8) + (y & 0x07); 16 | unsigned char vBit = bitTable[x & 0x07]; 17 | unsigned char i; 18 | /* Plot pixels */ 19 | for (i = 0; i < len; i++) { 20 | if (color) { 21 | bmp->bmpMem[pixByte] = bmp->bmpMem[pixByte] | vBit; 22 | } else { 23 | bmp->bmpMem[pixByte] = bmp->bmpMem[pixByte] & ~vBit; 24 | } 25 | y += 1; 26 | /* Increment based on char boundary */ 27 | if ((y & 7) > 0) { 28 | pixByte += 1; 29 | } else { 30 | pixByte += 313; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/vdc/print_vdc_bmp_col.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * Print with color. Optimized by setting VDC address once for each scan line. 13 | * Right now this is for 640x200 mode which doesn't support color. 14 | */ 15 | void printVdcBmpCol(const bitmap *bmp, const unsigned char x, const unsigned char y, const unsigned char color, const char *str) { 16 | unsigned int vdcMem = (unsigned int) bmp->bmpMem; 17 | unsigned int dispOfs = ((y * bmp->scrWidth) * 8) + vdcMem + x; 18 | unsigned int len = strlen(str); 19 | unsigned int i, chrOfs; 20 | unsigned char c; 21 | /* Draw 8 scan lines */ 22 | for (c = 0; c < 8; c++) { 23 | outVdc(vdcUpdAddrHi, (unsigned char) (dispOfs >> 8)); 24 | outVdc(vdcUpdAddrLo, (unsigned char) dispOfs); 25 | for (i = 0; i < len; i++) { 26 | chrOfs = (str[i] << 3) + c; 27 | outVdc(vdcCPUData, bmp->bmpChrMem[chrOfs]); 28 | } 29 | /* Next scan line */ 30 | dispOfs += bmp->scrWidth; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/demo/generate_sentence.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M sentence generator. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include "demo.h" 11 | /* 12 | * Generate random sentence about birds. 13 | */ 14 | char* generateSentence() { 15 | static char *articles[] = { "The", "A" }; 16 | static char *nouns[] = { "blue jay", "cardinal", "eastern phoebe", "grackle", "sandhill crane" }; 17 | static char *verbs[] = { "flies", "jumps", "sleeps", "eats", "walks" }; 18 | static char *adjectives[] = { "big", "small", "angry", "wet", "happy" }; 19 | char *sentence = malloc(100); 20 | int articleIndex = rand() % (sizeof(articles) / sizeof(articles[0])); 21 | int nounIndex = rand() % (sizeof(nouns) / sizeof(nouns[0])); 22 | int verbIndex = rand() % (sizeof(verbs) / sizeof(verbs[0])); 23 | int adjectiveIndex = rand() % (sizeof(adjectives) / sizeof(adjectives[0])); 24 | sentence[0] = '\0'; 25 | sprintf(sentence, "%s %s %s %s.", articles[articleIndex], adjectives[adjectiveIndex], nouns[nounIndex], verbs[verbIndex]); 26 | return sentence; 27 | } 28 | -------------------------------------------------------------------------------- /src/common/fcb_to_file_name.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * Common code. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | /* 15 | * Convert name and ext from FCB to normal 8.3 file name string. 16 | */ 17 | char* fcbToFileName(const struct fcb *fcb) { 18 | int i, j; 19 | // Allocate memory for 8.3 style file name 20 | char *fileName = (char*) malloc(13 * sizeof(char)); 21 | if (fileName == NULL) { 22 | // Memory allocation failed 23 | return NULL; 24 | } 25 | // Initialize the allocated memory to spaces 26 | memset(fileName, ' ', 12); 27 | // Copy name from FCB into fileName 28 | for (i = 0; i < 8 && fcb->name[i] != ' '; i++) { 29 | fileName[i] = fcb->name[i]; 30 | } 31 | fileName[i++] = '.'; 32 | // Copy extension from FCB into fileName 33 | for (j = 0; j < 3 && fcb->ext[j] != ' '; j++) { 34 | fileName[i++] = fcb->ext[j]; 35 | } 36 | // Ext starts with space, so terminate string 37 | if (j == 0) { 38 | fileName[--i] = '\0'; 39 | } else { 40 | fileName[i] = '\0'; 41 | } 42 | return fileName; 43 | } 44 | -------------------------------------------------------------------------------- /src/app/vdcdev.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * C128 keyboard demo. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #pragma output noprotectmsdos 17 | #pragma output CRT_STACK_SIZE = 1024 18 | 19 | /* 20 | * Initialize key scan, screen and console. 21 | */ 22 | void init(const console *con, const screen *scr) { 23 | initCia(); 24 | initVdcScr(scr, vdcScrMem, vdcColMem, vdcChrMem); 25 | initVdcScrMode(scr, scrBlack, scrBlack, scrWhite); 26 | initCon(con, scr); 27 | } 28 | 29 | /* 30 | * Restore VDC registers and CIA for CP/M return. 31 | */ 32 | void done() { 33 | doneVdc(); 34 | doneCia(); 35 | } 36 | 37 | /* 38 | * Run demo. 39 | */ 40 | void run(console *con) { 41 | runKeyDemo(con); 42 | } 43 | 44 | main() { 45 | /* Create screen struct */ 46 | screen *scr = (screen*) malloc(sizeof(screen)); 47 | /* Create console struct */ 48 | console *con = (console*) malloc(sizeof(console)); 49 | init(con, scr); 50 | run(con); 51 | done(); 52 | free(scr); 53 | free(con); 54 | } 55 | -------------------------------------------------------------------------------- /src/app/vdccon.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * C128 console demo. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "demo.h" 16 | 17 | #pragma output noprotectmsdos 18 | #pragma output CRT_STACK_SIZE = 1024 19 | 20 | /* 21 | * Initialize key scan, screen and console. 22 | */ 23 | void init(console *con, screen *scr) { 24 | initCia(); 25 | initVdcScr(scr, vdcScrMem, vdcColMem, vdcChrMem); 26 | initVdcScrMode(scr, scrBlack, scrBlack, scrWhite); 27 | initCon(con, scr); 28 | } 29 | 30 | /* 31 | * Restore VDC registers and CIA for CP/M return. 32 | */ 33 | void done() { 34 | doneVdc(); 35 | doneCia(); 36 | } 37 | 38 | /* 39 | * Run demo. 40 | */ 41 | void run(const console *con) { 42 | runConDemo(con, 200); 43 | } 44 | 45 | main() { 46 | /* Create screen struct */ 47 | screen *scr = (screen*) malloc(sizeof(screen)); 48 | /* Create console struct */ 49 | console *con = (console*) malloc(sizeof(console)); 50 | init(con, scr); 51 | run(con); 52 | done(); 53 | free(scr); 54 | free(con); 55 | } 56 | -------------------------------------------------------------------------------- /src/vic/draw_vic_line_vmc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Optimized vertical line algorithm uses less calculation than setVicPix. 12 | */ 13 | void drawVicLineVMc(const bitmap *bmp, const unsigned int x, const unsigned int y, const unsigned int len, 14 | const unsigned char color) { 15 | // Colors 0-3 pixels 16 | static const unsigned char bitTable[4][4] = { { 0x3f, 0xcf, 0xf3, 0xfc }, { 0x40, 0x10, 0x04, 0x01 }, 17 | { 0x80, 0x20, 0x08, 0x02 }, { 0xc0, 0x30, 0x0c, 0x03 } }; 18 | unsigned int pixByte = bmp->scrWidth * (y & 0xf8) + (x << 1 & 0x1f8) + (y & 0x07); 19 | unsigned char i; 20 | unsigned char vBit = bitTable[color][x & 0x03]; 21 | /* Plot pixels */ 22 | for (i = 0; i < len; i++) { 23 | if (color) { 24 | bmp->bmpMem[pixByte] = bmp->bmpMem[pixByte] | vBit; 25 | } else { 26 | bmp->bmpMem[pixByte] = bmp->bmpMem[pixByte] & vBit; 27 | } 28 | y += 1; 29 | /* Increment based on char boundary */ 30 | if ((y & 7) > 0) { 31 | pixByte += 1; 32 | } else { 33 | pixByte += 313; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/app/vdcconi.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * C128 console demo. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "demo.h" 16 | 17 | #pragma output noprotectmsdos 18 | #pragma output CRT_STACK_SIZE = 1024 19 | 20 | /* 21 | * Initialize key scan, screen and console. 22 | */ 23 | void init(console *con, screen *scr) { 24 | initCia(); 25 | initVdcIntScr(scr, vdcScrIntMem, vdcColIntMem, vdcChrIntMem); 26 | initVdcIntScrMode(scr, scrBlack, scrBlack, scrWhite); 27 | initCon(con, scr); 28 | } 29 | 30 | /* 31 | * Restore VDC registers and CIA for CP/M return. 32 | */ 33 | void done() { 34 | doneVdc(); 35 | doneCia(); 36 | } 37 | 38 | /* 39 | * Run demo. 40 | */ 41 | void run(const console *con) { 42 | runConDemo(con, 200); 43 | } 44 | 45 | main() { 46 | /* Create screen struct */ 47 | screen *scr = (screen*) malloc(sizeof(screen)); 48 | /* Create console struct */ 49 | console *con = (console*) malloc(sizeof(console)); 50 | init(con, scr); 51 | run(con); 52 | done(); 53 | free(scr); 54 | free(con); 55 | } 56 | -------------------------------------------------------------------------------- /src/vic/fill_vic_mem_col.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Copyright (c) Steven P. Goldsmith. All rights reserved. 3 | ; 4 | ; Assembled with HI-TECH C 3.09 (CP/M-80) ZAS. 5 | ; 6 | ; Fill VIC color memory. 7 | ; 8 | 9 | SECTION code_clib 10 | PUBLIC fillVicMemCol 11 | PUBLIC _fillVicMemCol 12 | 13 | ;return address 14 | 15 | return: 16 | 17 | defw 0 18 | 19 | fillVicMemCol: 20 | _fillVicMemCol: 21 | pop hl ; Return address? 22 | ld (return),hl ; Save return address 23 | pop hl ; Color 24 | ld a,l ; a reg holds color 25 | pop de ; Length 26 | pop bc ; Address 27 | push bc 28 | push de 29 | push hl 30 | ld hl,(return) ; Get saved return address 31 | push hl 32 | ld l,a 33 | rep1: 34 | out (c),l ; Set color memory 35 | inc bc ; Set for next address 36 | dec de ; Length -= 1 37 | ld a,d 38 | or e 39 | jr nz,rep1 40 | ret 41 | -------------------------------------------------------------------------------- /src/common/init_dir.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * Common code. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | * Initialize BDOS to retrieve directory. Search for the first occurrence of the 14 | * specified file; the filename should be stored in the supplied FCB. The filename 15 | * can include ? marks, which match anything on disc. If the first byte of the FCB 16 | * is ?, then any directory entry (including disc labels, date stamps etc.) will 17 | * match. The EX byte is also checked; normally it should be set to zero, but if it 18 | * is set to ? then all suitable extents are matched. 19 | */ 20 | int initDir(int login, int user, struct fcb *fcb, unsigned char dmaBuf[]) { 21 | int retVal; 22 | // Login into disk 23 | retVal = bdos(CPM_LGIN, login); 24 | if (retVal == 0) { 25 | // Set user 26 | retVal = bdos(CPM_SUID, user); 27 | if (retVal == 0) { 28 | // Set the Direct Memory Access address 29 | retVal = bdos(CPM_SDMA, dmaBuf); 30 | if (retVal == 0) { 31 | // This should return -1 if no matching search or other failure 32 | retVal = bdos(CPM_FFST, fcb); 33 | } 34 | } 35 | } 36 | return retVal; 37 | } 38 | -------------------------------------------------------------------------------- /src/console/print_wrap_con.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M console print. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | void printWrapCon(const console *con, const char *str) { 11 | /* Screen width should not exceed buffer size +1 */ 12 | char buffer[81]; 13 | unsigned int i = 0, wordLen, len = strlen(str); 14 | int wordStart = -1, wordEnd = -1; 15 | unsigned char maxLine = con->scr->scrWidth - 1, buf = 0, maxBuf = sizeof(buffer) - 1; 16 | while (i < len && buf < maxBuf) { 17 | /* Load word buffer using space delimiter */ 18 | while (i < len && wordEnd < 0 && buf < maxBuf) { 19 | /* Find first non space char */ 20 | if (str[i] != ' ') { 21 | if (wordStart < 0) { 22 | wordStart = i; 23 | } 24 | buffer[buf++] = str[i]; 25 | } else { 26 | /* End of word including space */ 27 | if (wordEnd < 0) { 28 | buffer[buf++] = str[i]; 29 | wordEnd = i; 30 | }; 31 | } 32 | i++; 33 | } 34 | if (buf > 0) { 35 | buffer[buf] = 0x00; 36 | wordLen = strlen(buffer); 37 | if (con->curX + wordLen > maxLine) { 38 | printLineCon(con, ""); 39 | } 40 | printCon(con, buffer); 41 | wordStart = -1; 42 | wordEnd = -1; 43 | buf = 0; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/app/ciademo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * CIA 2 timer A and B millisecond demo. CIA 1 TOD used to calibrate. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | * 8 | */ 9 | 10 | #pragma output noprotectmsdos 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | main() { 17 | unsigned long i, startCia, endCia; 18 | unsigned int timerVal; 19 | unsigned char tens; 20 | if (inp(cia1 + ciaCtrlRegA) & 0x80) { 21 | printf("\nCIA 1 50 Hz\n"); 22 | } else { 23 | printf("\nCIA 1 60 Hz\n"); 24 | } 25 | printf("Empty loop elapsed time test.\n"); 26 | initCia(); 27 | /* Timer A counts milliseconds up to 65535 times or ~65 seconds */ 28 | startTimerAB(cia2, ciaMs, 0xffff, ciaCountA); 29 | tens = inp(cia1 + ciaTodTen); 30 | /* Wait for tenth of a second to change */ 31 | while (inp(cia1 + ciaTodTen) == tens) 32 | ; 33 | startCia = todToMs(cia1); 34 | outp(cia2 + ciaCtrlRegA, ciaCpuCont); 35 | for (i = 0; i < 130000; ++i) { 36 | } 37 | /* Stop timer A/B */ 38 | outp(cia2 + ciaCtrlRegA, ciaStopTimer); 39 | endCia = todToMs(cia1); 40 | timerVal = 0xffff - (inp(cia2 + ciaTimerBHi) * 256 + inp(cia2 + ciaTimerBLo)); 41 | printf("Milliseconds CIA timer %u, CIA TOD %lu\n", timerVal, (endCia - startCia)); 42 | doneCia(); 43 | } 44 | -------------------------------------------------------------------------------- /src/app/cpmdir.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * Get CP/M dir. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | /* 16 | * Print the doubly linked list. 17 | */ 18 | void printList(node *head) { 19 | while (head != NULL) { 20 | printf("%s\n", head->data); 21 | head = head->next; 22 | } 23 | } 24 | 25 | int main(void) { 26 | int retVal, dmaOffset; 27 | node *head = NULL; 28 | struct fcb dirFcb, retFcb; 29 | // FCB is 36 bytes, but only 32 are returned by CPM_FFST and CPM_FNXT calls 30 | unsigned char dmaBuf[144]; 31 | // Zero out FCB 32 | memset(dirFcb, 0, sizeof(dirFcb)); 33 | memcpy(dirFcb.name, "????????", sizeof(dirFcb.name)); 34 | memcpy(dirFcb.ext, "???", sizeof(dirFcb.ext)); 35 | // Use A0 36 | retVal = initDir(0, 0, &dirFcb, dmaBuf); 37 | if (retVal == 0) { 38 | // Copy first file name to FCB from DMA buffer 39 | memcpy(&retFcb, dmaBuf, sizeof(struct fcb)); 40 | // Add to linked list 41 | insertEnd(&head, fcbToFileName(&retFcb)); 42 | // Get the rest of the file names. 43 | getDir(&dirFcb, dmaBuf, head); 44 | printList(head); 45 | freeList(head); 46 | return EXIT_SUCCESS; 47 | 48 | } 49 | return EXIT_FAILURE; 50 | } 51 | -------------------------------------------------------------------------------- /src/vdc/init_vdc_int_bmp_mode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8563 VDC bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Copy fonts to memory for VDC interlace mode and clear screen. 12 | */ 13 | void initVdcIntBmpMode(const bitmap *bmp, const unsigned char *chrMem, const unsigned char bgCol, const unsigned char fgCol) { 14 | saveVdc(); 15 | /* Turn off cursor for bitmap mode */ 16 | setVdcCursor(0, 0, vdcCurNone); 17 | /* Copy VDC char sets to mem bufer */ 18 | copyVdcChrMem(chrMem, 0x2000, 512); 19 | // Set 64K mode if not set 20 | if (!isVdc64k()) { 21 | setVdc64k(); 22 | } 23 | outVdc(vdcHzTotal, 126); 24 | outVdc(vdcHzDisp, 80); 25 | outVdc(vdcHzSyncPos, 102); 26 | outVdc(vdcVtTotal, 76); 27 | outVdc(vdcVtTotalAdj, 6); 28 | outVdc(vdcVtDisp, 76); 29 | outVdc(vdcVtSyncPos, 71); 30 | outVdc(vdcIlaceMode, 3); 31 | outVdc(vdcChTotalVt, 6); 32 | outVdc(vdcVtSmScroll, 0); 33 | outVdc(vdcHzSmScroll, 135); 34 | outVdc(vdcAddrIncPerRow, 0); 35 | /* Set bitmap mode */ 36 | setVdcFgBg(bmp->color[fgCol], bmp->color[bgCol]); 37 | setVdcAttrsOff(); 38 | setVdcBmpMode((unsigned int) bmp->bmpMem, (unsigned int) bmp->bmpColMem); 39 | //(bmp->clearBmpCol)(bmp, (bmp->color[bmpWhite])); 40 | //(bmp->clearBmp)(bmp, 0); 41 | } 42 | -------------------------------------------------------------------------------- /.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/vdc/init_vdc_scr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Configure screen struct for VDC. 12 | */ 13 | void initVdcScr(const screen *scr, const unsigned int scrMem, const unsigned int colMem, const unsigned int chrMem) { 14 | static unsigned char vdcColors[16] = { vdcBlack, vdcWhite, vdcDarkRed, vdcLightCyan, 15 | vdcLightPurple, vdcDarkGreen, vdcDarkBlue, vdcLightYellow, 16 | vdcDarkPurple, vdcDarkYellow, vdcLightRed, vdcDarkCyan, vdcDarkGray, 17 | vdcLightGreen, vdcLightBlue, vdcMedGray }; 18 | /* Map colors */ 19 | unsigned char i, len = sizeof(vdcColors); 20 | for (i = 0; i < len; i++) { 21 | scr->color[i] = vdcAltChrSet | vdcColors[i]; 22 | } 23 | scr->scrWidth = 80; 24 | scr->scrHeight = 25; 25 | scr->scrSize = scr->scrWidth * scr->scrHeight; 26 | scr->chrMem = (unsigned char*) chrMem; 27 | scr->scrMem = (unsigned char*) scrMem; 28 | scr->scrColMem = (unsigned char*) vdcColMem; 29 | scr->clearScr = clearVdcScr; 30 | scr->clearScrCol = clearVdcScrCol; 31 | scr->print = printVdc; 32 | scr->printCol = printVdcCol; 33 | scr->scrollUp = scrollVdcUp; 34 | scr->scrollUpCol = scrollVdcUpCol; 35 | scr->fillMem = fillVdcMem; 36 | scr->copyScrToStr = copyVdcToStr; 37 | } 38 | -------------------------------------------------------------------------------- /src/graphics/draw_line.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M bitmap line abstraction. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Bresenham’s line algorithm. Color is 1 to set or 0 to clear pixel. 12 | */ 13 | void drawLine(const bitmap *bmp, const int x0, const int y0, const int x1, const int y1, const unsigned char color) { 14 | int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1; 15 | int dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1; 16 | int err = (dx > dy ? dx : -dy) / 2, e2; 17 | /* Horizontal line */ 18 | if ((bmp->drawLineH != NULL) && (y0 == y1)) { 19 | if (x0 < x1) { 20 | (bmp->drawLineH)(bmp, x0, y0, dx + 1, color); 21 | } else { 22 | (bmp->drawLineH)(bmp, x1, y1, dx + 1, color); 23 | } 24 | /* Vertical line */ 25 | } else if ((bmp->drawLineV != NULL) && (x0 == x1)) { 26 | if (y0 < y1) { 27 | (bmp->drawLineV)(bmp, x0, y0, dy + 1, color); 28 | } else { 29 | (bmp->drawLineV)(bmp, x1, y1, dy + 1, color); 30 | } 31 | } else { 32 | /* Bresenham line */ 33 | for (;;) { 34 | (bmp->setPixel)(bmp, x0, y0, color); 35 | if (x0 == x1 && y0 == y1) 36 | break; 37 | e2 = err; 38 | if (e2 > -dx) { 39 | err -= dy; 40 | x0 += sx; 41 | } 42 | if (e2 < dy) { 43 | err += dx; 44 | y0 += sy; 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/vdc/init_vdc_int_scr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8563 VDC screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Configure screen struct for VDC interlace mode. 12 | */ 13 | void initVdcIntScr(const screen *scr, const unsigned int scrMem, const unsigned int colMem, const unsigned int chrMem) { 14 | static unsigned char vdcColors[16] = { vdcBlack, vdcWhite, vdcDarkRed, vdcLightCyan, 15 | vdcLightPurple, vdcDarkGreen, vdcDarkBlue, vdcLightYellow, 16 | vdcDarkPurple, vdcDarkYellow, vdcLightRed, vdcDarkCyan, vdcDarkGray, 17 | vdcLightGreen, vdcLightBlue, vdcMedGray }; 18 | /* Map colors */ 19 | unsigned char i, len = sizeof(vdcColors); 20 | for (i = 0; i < len; i++) { 21 | scr->color[i] = vdcAltChrSet | vdcColors[i]; 22 | } 23 | scr->scrWidth = 80; 24 | scr->scrHeight = 50; 25 | scr->scrSize = scr->scrWidth * scr->scrHeight; 26 | scr->chrMem = (unsigned char*) chrMem; 27 | scr->scrMem = (unsigned char*) scrMem; 28 | scr->scrColMem = (unsigned char*) colMem; 29 | scr->clearScr = clearVdcScr; 30 | scr->clearScrCol = clearVdcScrCol; 31 | scr->print = printVdc; 32 | scr->printCol = printVdcCol; 33 | scr->scrollUp = scrollVdcUp; 34 | scr->scrollUpCol = scrollVdcUpCol; 35 | scr->fillMem = fillVdcMem; 36 | scr->copyScrToStr = copyVdcToStr; 37 | } 38 | -------------------------------------------------------------------------------- /src/console/scroll_con.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M console print. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * Scroll and update cursor position based on string length. 13 | */ 14 | void scrollCon(const console *con, const char *str) { 15 | screen *scr = con->scr; 16 | unsigned int scrOfs = offsetCon(con); 17 | unsigned int len = strlen(str); 18 | /* Do we need to scroll? */ 19 | if (scrOfs + len > scr->scrSize) { 20 | unsigned char y = (scrOfs + len - scr->scrSize) / scr->scrWidth + 1; 21 | /* First scroll, so bottom line can be blanked */ 22 | if (con->colorOn) { 23 | (scr->scrollUpCol)(scr, 0, 0, scr->scrWidth - 1, scr->scrHeight - 1); 24 | } else { 25 | (scr->scrollUp)(scr, 0, 0, scr->scrWidth - 1, scr->scrHeight - 1); 26 | } 27 | (scr->fillMem)(scr->scrMem + scr->scrSize - scr->scrWidth, scr->scrWidth, 32); 28 | scrOfs = scrOfs - (y * scr->scrWidth); 29 | y -= 1; 30 | /* Scroll Y lines */ 31 | for (; y > 0; y--) { 32 | if (con->colorOn) { 33 | (scr->scrollUpCol)(scr, 0, 0, scr->scrWidth - 1, scr->scrHeight - 1); 34 | } else { 35 | (scr->scrollUp)(scr, 0, 0, scr->scrWidth - 1, scr->scrHeight - 1); 36 | } 37 | } 38 | /* Set new cursor position for print */ 39 | setCurCon(con, scrOfs); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/vic/init_vic_bmp_mode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | /* 13 | * Copy VDC char set to memory, set screen color, MMU bank, VIC bank, screen 14 | * memory and bitmap memory. Clear bitmap memory, color memory then enable screen. 15 | */ 16 | void initVicBmpMode(const bitmap *bmp, const unsigned char bgCol, const unsigned char fgCol, const unsigned char pixCol) { 17 | unsigned char vicBank; 18 | saveVic(); 19 | /* Set border and background color */ 20 | outp(vicBorderCol, bmp->color[fgCol]); 21 | outp(vicBgCol0, bmp->color[bgCol]); 22 | /* Clear bitmap */ 23 | (bmp->clearBmp)(bmp, 0); 24 | /* Set foreground and background pixel colors */ 25 | (bmp->clearBmpCol)(bmp, (bmp->color[pixCol] << 4) | (bmp->color[bgCol] & 0x0f)); 26 | /* Copy VDC alt char set to VIC mem */ 27 | copyVdcChrMem(bmp->bmpChrMem, 0x3000, 256); 28 | /* Set standard bitmap mode using MMU bank 1 */ 29 | vicBank = (unsigned int) bmp->bmpMem / 16384; 30 | setVicBmpMode(1, vicBank, ((unsigned int) bmp->bmpColMem - (vicBank * 16384)) / 1024, 31 | ((unsigned int) bmp->bmpMem - (vicBank * 16384)) / 8192, 0); 32 | /* Enable screen */ 33 | outp(vicCtrlReg1, (inp(vicCtrlReg1) | 0x10)); 34 | } 35 | -------------------------------------------------------------------------------- /src/sid/read_sid_pots.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6581/8580 SID functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * Read all pots (values are passed by reference). 13 | * 14 | * Note CIA 2 timer A is used. 15 | */ 16 | void readSidPots(const unsigned char *x1, const unsigned char *y1, const unsigned char *x2, const unsigned char *y2) { 17 | unsigned char saveReg = inp(cia1 + ciaDdrA); 18 | // Set bits 6 and 7 to output 19 | outp(cia1 + ciaDdrA, ciaPots); 20 | // Set 4066 to read port 1 pots 21 | outp(cia1 + ciaDataA, ciaPotsPort1); 22 | // Clear all CIA 2 IRQ enable bits 23 | outp(cia2+ciaIcr, ciaClearIcr); 24 | // 1.6 ms (625 Hz) delay to get stable reading 25 | startTimerA(cia2, 625, ciaCpuOne); 26 | while ((inp(cia2 + ciaIcr) & 0x01) == 0) 27 | ; 28 | // Read pots 29 | *x1 = inp(sidPotX); 30 | *y1 = inp(sidPotY); 31 | // Set 4066 to read port 2 pots 32 | outp(cia1 + ciaDataA, ciaPotsPort2); 33 | // Clear all CIA 2 IRQ enable bits 34 | outp(cia2+ciaIcr, ciaClearIcr); 35 | // 1.6 ms (625 Hz) delay to get stable reading 36 | startTimerA(cia2, 625, ciaCpuOne); 37 | while ((inp(cia2 + ciaIcr) & 0x01) == 0) 38 | ; 39 | // Read pots 40 | *x2 = inp(sidPotX); 41 | *y2 = inp(sidPotY); 42 | // Restore data dir reg 43 | outp(cia1 + ciaDdrA, saveReg); 44 | } 45 | -------------------------------------------------------------------------------- /src/app/vdcgraph.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * 8563 VDC bitmap demo. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "demo.h" 15 | 16 | #pragma output noprotectmsdos 17 | #pragma output CRT_STACK_SIZE = 1024 18 | 19 | /* 20 | * Configure CIA, copy fonts to memory, set screen struct for VDC and clear screen. 21 | */ 22 | void init(const bitmap *bmp, const unsigned char *chr) { 23 | initCia(); 24 | initVdcBmp(bmp, vdcScrMem, vdcColMem, chr); 25 | initVdcBmpMode(bmp, chr, bmpBlack, bmpWhite); 26 | } 27 | 28 | /* 29 | * Restore VDC registers, screen color, screen memory and char set memory location for CP/M return. 30 | */ 31 | void done(const bitmap *bmp, const unsigned char *chr) { 32 | doneVdc(); 33 | doneCia(); 34 | /* Copy character set from memory to VDC */ 35 | copyVdcMemChr(chr, 0x2000, 512); 36 | } 37 | 38 | /* 39 | * Run demo. 40 | */ 41 | void run(const bitmap *bmp) { 42 | runGraphDemo(bmp); 43 | } 44 | 45 | main() { 46 | /* Save both VDC char sets */ 47 | unsigned char *chr = (unsigned char*) malloc(4096); 48 | /* Create screen struct */ 49 | bitmap *bmp = (bitmap*) malloc(sizeof(bitmap)); 50 | init(bmp, chr); 51 | run(bmp); 52 | done(bmp, chr); 53 | /* Free memory */ 54 | free(chr); 55 | free(bmp); 56 | } 57 | -------------------------------------------------------------------------------- /include/demo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M graphics abstraction. 3 | * 4 | * Demo functions. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #ifndef _DEMO_H 10 | #define _DEMO_H 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | extern void __LIB__ waitKey(const screen *scr); 17 | extern void __LIB__ readLine(const console *con); 18 | extern void __LIB__ keyboard(const screen *scr); 19 | extern void __LIB__ runKeyDemo(const console *con); 20 | extern char __LIB__ *generateSentence(); 21 | extern void __LIB__ runConDemo(const console *con, const unsigned char sentences); 22 | extern void __LIB__ runGraphDemo(const bitmap *bmp) ; 23 | extern void __LIB__ runGraphDemoI(const console *con, const bitmap *bmp, const unsigned int code); 24 | extern void __LIB__ runDualDemo(const console *vicCon, const console *vdcCon); 25 | extern void __LIB__ runTextDemo(const console *vicCon, const console *vdcCon, const unsigned int cpmPrintMs, const unsigned int cpmScrollMs, const unsigned int lines); 26 | extern unsigned int __LIB__ cpmPrint(const char *str, const unsigned int lines); 27 | extern unsigned int __LIB__ cpmScroll(const unsigned int lines); 28 | extern void __LIB__ runTextDemo(const console *vicCon, const console *vdcCon, const unsigned int cpmPrintMs, const unsigned int cpmScrollMs, const unsigned int lines) ; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/app/vicdev.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * C128 keyboard demo. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #pragma output noprotectmsdos 17 | #pragma output CRT_STACK_SIZE = 1024 18 | // Protect VIC memory < 0x8000 19 | #pragma output CRT_HEAP_ADDRESS = 0x8000 20 | 21 | /* 22 | * Initialize key scan, screen and console. 23 | */ 24 | void init(const console *con, const screen *scr) { 25 | initCia(); 26 | /* Use ram at end of bank 1 for screen and copy VDC character set just above that */ 27 | initVicScr(scr, 0x7c00, 0x7000); 28 | initVicScrMode(scr, scrBlack, scrBlack, scrWhite); 29 | initCon(con, scr); 30 | } 31 | 32 | /* 33 | * Restore VIC back to CP/M defaults. 34 | */ 35 | void done() { 36 | doneVic(); 37 | doneCia(); 38 | } 39 | 40 | /* 41 | * Run demo. 42 | */ 43 | void run(const console *con) { 44 | runKeyDemo(con); 45 | } 46 | 47 | /* 48 | * Configure memory to protect VIC and run demo. 49 | */ 50 | main() { 51 | /* Create screen struct */ 52 | screen *scr = (screen*) malloc(sizeof(screen)); 53 | /* Create console struct */ 54 | console *con = (console*) malloc(sizeof(console)); 55 | init(con, scr); 56 | run(con); 57 | done(); 58 | /* Free memory */ 59 | free(scr); 60 | free(con); 61 | } 62 | -------------------------------------------------------------------------------- /src/app/viccon.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * C128 console demo. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "demo.h" 16 | 17 | #pragma output noprotectmsdos 18 | #pragma output CRT_STACK_SIZE = 1024 19 | // Protect VIC memory < 0x8000 20 | #pragma output CRT_HEAP_ADDRESS = 0x8000 21 | 22 | /* 23 | * Initialize key scan, screen and console. 24 | */ 25 | void init(const console *con, const screen *scr) { 26 | initCia(); 27 | /* Use ram at end of bank 1 for screen and copy VDC character set just above that */ 28 | initVicScr(scr, 0x7c00, 0x7000); 29 | initVicScrMode(scr, scrBlack, scrBlack, scrWhite); 30 | initCon(con, scr); 31 | } 32 | 33 | /* 34 | * Restore VIC back to CP/M defaults. 35 | */ 36 | void done() { 37 | doneVic(); 38 | doneCia(); 39 | } 40 | 41 | /* 42 | * Run demo. 43 | */ 44 | void run(const console *con) { 45 | runConDemo(con, 100); 46 | } 47 | 48 | /* 49 | * Configure memory to protect VIC and run demo. 50 | */ 51 | main() { 52 | /* Create screen struct */ 53 | screen *scr = (screen*) malloc(sizeof(screen)); 54 | /* Create console struct */ 55 | console *con = (console*) malloc(sizeof(console)); 56 | init(con, scr); 57 | run(con); 58 | done(); 59 | /* Free memory */ 60 | free(scr); 61 | free(con); 62 | } 63 | -------------------------------------------------------------------------------- /src/demo/run_con_demo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M console. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | void randSentence(const console *con, const unsigned char sentences, const unsigned char color) { 14 | static unsigned char colors[] = { scrGreen, scrLightGreen, scrBlue, scrLightBlue, 15 | scrRed, scrLightRed }; 16 | unsigned char i; 17 | char *str; 18 | if (color) { 19 | printWrapCon(con, "Here we use the console functions with color which are slower than no color."); 20 | con->colorOn = 1; 21 | } else { 22 | printWrapCon(con, "Here we use the console functions without color which are faster."); 23 | con->colorOn = 0; 24 | } 25 | waitKey(con->scr); 26 | clearHomeCon(con); 27 | srand(inp(vicRaster)); 28 | for (i = 0; i < sentences; i++) { 29 | if (color) { 30 | con->color = colors[rand() % (sizeof(colors) / sizeof(colors[0]))]; 31 | } 32 | str = generateSentence(); 33 | printWrapCon(con, str); 34 | free(str); 35 | if (con->curX != 0) { 36 | printCon(con, " "); 37 | } 38 | } 39 | printLineCon(con, ""); 40 | waitKey(con->scr); 41 | clearHomeCon(con); 42 | } 43 | 44 | /* 45 | * Run console demo. 46 | */ 47 | void runConDemo(const console *con, const unsigned char sentences) { 48 | randSentence(con, sentences, 0); 49 | randSentence(con, sentences, 1); 50 | } 51 | -------------------------------------------------------------------------------- /src/graphics/draw_ellipse.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M bitmap ellipse abstraction. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | 9 | /* 10 | * Draw ellipse using the midpoint algorithm. The algorithm works by dividing 11 | * the ellipse into two halves and drawing each half separately. 12 | */ 13 | void drawEllipse(const bitmap *bmp, const int xc, const int yc, const int a, const int b, const unsigned char color) { 14 | long a2 = (long) a * a; 15 | long b2 = (long) b * b; 16 | long fa2 = 4 * a2, fb2 = 4 * b2; 17 | long sigma; 18 | int x, y; 19 | /* First half */ 20 | for (x = 0, y = b, sigma = 2 * b2 + a2 * (1 - 2 * b); b2 * x <= a2 * y; x++) { 21 | (bmp->setPixel)(bmp, xc + x, yc + y, color); 22 | (bmp->setPixel)(bmp, xc - x, yc + y, color); 23 | (bmp->setPixel)(bmp, xc + x, yc - y, color); 24 | (bmp->setPixel)(bmp, xc - x, yc - y, color); 25 | if (sigma >= 0) { 26 | sigma += fa2 * (1 - y); 27 | y--; 28 | } 29 | sigma += b2 * ((4 * x) + 6); 30 | } 31 | /* Second half */ 32 | for (x = a, y = 0, sigma = 2 * a2 + b2 * (1 - 2 * a); a2 * y <= b2 * x; y++) { 33 | (bmp->setPixel)(bmp, xc + x, yc + y, color); 34 | (bmp->setPixel)(bmp, xc - x, yc + y, color); 35 | (bmp->setPixel)(bmp, xc + x, yc - y, color); 36 | (bmp->setPixel)(bmp, xc - x, yc - y, color); 37 | if (sigma >= 0) { 38 | sigma += fb2 * (1 - x); 39 | x--; 40 | } 41 | sigma += a2 * ((4 * y) + 6); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/vic/init_vic_scr_mode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | /* 13 | * Initialize VIC using VDC alt character set in RAM. 14 | */ 15 | void initVicScrMode(const screen *scr, const unsigned char bgCol, const unsigned char fgCol, const unsigned char chrCol) { 16 | unsigned char vicBank; 17 | saveVic(); 18 | /* Black screen and border */ 19 | outp(vicBorderCol, scr->color[fgCol]); 20 | outp(vicBgCol0, scr->color[bgCol]); 21 | /* Clear color to chrCol */ 22 | (scr->clearScrCol)(scr, chrCol); 23 | /* Clear screen to spaces */ 24 | (scr->clearScr)(scr, 32); 25 | /* Only copy VDC character set if RAM used */ 26 | if ((unsigned int) scr->chrMem != 0x1000 && (unsigned int) scr->chrMem != 0x1800 && (unsigned int) scr->chrMem != 0x9000 27 | && (unsigned int) scr->chrMem != 0x9800) { 28 | /* Copy VDC alt char set to VIC mem */ 29 | copyVdcChrMem(scr->chrMem, 0x3000, 256); 30 | } 31 | /* Set standard character mode using MMU bank 1 and set VIC based on scrMem location */ 32 | vicBank = (unsigned int) scr->scrMem / 16384; 33 | setVicChrMode(1, vicBank, ((unsigned int) scr->scrMem - (vicBank * 16384)) / 1024, 34 | ((unsigned int) scr->chrMem - (vicBank * 16384)) / 2048); 35 | /* Enable screen */ 36 | outp(vicCtrlReg1, ((inp(vicCtrlReg1) | 0x10) & 0x7f)); 37 | } 38 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Change this as needed 2 | export ZCCCFG := $(HOME)/z88dk/lib/config 3 | 4 | # Compiler 5 | CC = zcc 6 | 7 | # Assembler 8 | AS = z88dk-z80asm 9 | 10 | # Compiler flags 11 | CFLAGS = +cpm -vn -I$(HOME)/z88dk/include -I./include 12 | 13 | # Source directory 14 | SRC_DIR = src 15 | # Object directory 16 | BUILD_DIR = build 17 | 18 | # Find all subdirectories of src excluding src/app and its subdirectories 19 | SUBDIRS := $(shell find $(SRC_DIR) -mindepth 1 -maxdepth 1 -type d ! -name app) 20 | 21 | # Generate object file names for both C and assembly files 22 | OBJS := $(patsubst $(SRC_DIR)/%, $(BUILD_DIR)/%, \ 23 | $(patsubst %.c, %.o, $(foreach dir,$(SUBDIRS),$(wildcard $(dir)/*.c))) \ 24 | $(patsubst %.asm, %.o, $(foreach dir,$(SUBDIRS),$(wildcard $(dir)/*.asm)))) 25 | 26 | # Targets 27 | all: $(OBJS) 28 | 29 | # Rule to compile C source files into object files 30 | $(BUILD_DIR)/%.o: $(SRC_DIR)/%.c 31 | @mkdir -p $(dir $@) 32 | $(CC) $(CFLAGS) -c $< -o $@ 33 | 34 | # Rule to compile assembly source files into object files 35 | $(BUILD_DIR)/%.o: $(SRC_DIR)/%.asm 36 | @mkdir -p $(dir $@) 37 | $(AS) $< -o$@ 38 | 39 | # Target to create lib files 40 | lib: c3l.lst 41 | @mkdir -p $(BUILD_DIR)/lib 42 | $(AS) -d -x./build/lib/c3l @$< 43 | 44 | # Target to create lib files 45 | demo: demo.lst 46 | @mkdir -p $(BUILD_DIR)/lib 47 | $(AS) -d -x./build/lib/demo @$< 48 | 49 | 50 | # Clean rule 51 | clean: 52 | @rm -rf $(BUILD_DIR) 53 | 54 | .PHONY: all lib demo clean 55 | -------------------------------------------------------------------------------- /src/vic/init_vic_scr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe screen functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Initialize screen struct for VIC. 12 | */ 13 | void initVicScr(const screen *scr, const unsigned int scrMem, const unsigned int chrMem) { 14 | static unsigned char vicColors[16] = { vicBlack, vicWhite, vicRed, vicCyan, 15 | vicPurple, vicGreen, vicBlue, vicYellow, vicOrange, vicBrown, vicLightRed, 16 | vicDarkGray, vicMedGray, vicLightGreen, vicLightBlue, vicLightGray }; 17 | /* Map colors */ 18 | unsigned char i, len = sizeof(vicColors); 19 | for (i = 0; i < len; i++) { 20 | scr->color[i] = vicColors[i]; 21 | } 22 | scr->scrWidth = 40; 23 | scr->scrHeight = 25; 24 | scr->scrSize = scr->scrWidth * scr->scrHeight; 25 | scr->chrMem = (unsigned char*) chrMem; 26 | scr->scrMem = (unsigned char*) scrMem; 27 | scr->scrColMem = (unsigned char*) vicColMem; 28 | scr->clearScr = clearVicScr; 29 | scr->clearScrCol = clearVicCol; 30 | /* Assign print functions based on character set address */ 31 | if (chrMem == 0x1000 || chrMem == 0x1800 || chrMem == 0x9000 || chrMem == 0x9800) { 32 | /* ROM */ 33 | scr->print = printVicPet; 34 | scr->printCol = printVicColPet; 35 | } else { 36 | /* RAM */ 37 | scr->print = printVic; 38 | scr->printCol = printVicCol; 39 | } 40 | scr->scrollUp = scrollVicUp; 41 | scr->scrollUpCol = scrollVicUpCol; 42 | scr->fillMem = fillVicMem; 43 | scr->copyScrToStr = copyVicToStr; 44 | } 45 | -------------------------------------------------------------------------------- /src/vic/init_vic_bmp_mode_mc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | /* 13 | * Copy VDC char set to memory, set screen color, MMU bank, VIC bank, screen 14 | * memory and bitmap memory. Clear bitmap memory, color memory then enable screen. 15 | */ 16 | void initVicBmpModeMc(const bitmap *bmp, const unsigned char bgCol, const unsigned char fgCol, const unsigned char pixCol1, 17 | const unsigned char pixCol2, const unsigned char pixCol3) { 18 | unsigned char vicBank; 19 | saveVic(); 20 | /* Set border and background color */ 21 | outp(vicBorderCol, bmp->color[fgCol]); 22 | outp(vicBgCol0, bmp->color[bgCol]); 23 | /* Clear bitmap */ 24 | (bmp->clearBmp)(bmp, 0); 25 | /* Set foreground and background pixel colors */ 26 | (bmp->clearBmpCol)(bmp, (bmp->color[pixCol2] << 4) | (bmp->color[pixCol1] & 0x0f)); 27 | // Set pixel color 3 28 | fillVicMemCol(vicColMem, bmp->bmpColSize, bmp->color[pixCol3]); 29 | // Copy VDC alt char set to VIC mem, but this is not multicolor 30 | copyVdcChrMem(bmp->bmpChrMem, 0x3000, 256); 31 | // Set multicolor bitmap mode using MMU bank 1 32 | vicBank = (unsigned int) bmp->bmpMem / 16384; 33 | setVicBmpMode(1, vicBank, ((unsigned int) bmp->bmpColMem - (vicBank * 16384)) / 1024, 34 | ((unsigned int) bmp->bmpMem - (vicBank * 16384)) / 8192, 1); 35 | // Enable screen 36 | outp(vicCtrlReg1, (inp(vicCtrlReg1) | 0x10)); 37 | } 38 | -------------------------------------------------------------------------------- /src/vic/init_vic_bmp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Initialize bitmap struct for VIC. 12 | */ 13 | void initVicBmp(const bitmap *bmp, const unsigned int bmpMem, const unsigned int colMem, const unsigned int chrMem) { 14 | static unsigned char vicColors[16] = { vicBlack, vicWhite, vicRed, vicCyan, 15 | vicPurple, vicGreen, vicBlue, vicYellow, vicOrange, vicBrown, vicLightRed, 16 | vicDarkGray, vicMedGray, vicLightGreen, vicLightBlue, vicLightGray }; 17 | /* Map colors */ 18 | unsigned char i, len = sizeof(vicColors); 19 | for (i = 0; i < len; i++) { 20 | bmp->color[i] = vicColors[i]; 21 | } 22 | /* VIC bitmap configuration */ 23 | bmp->bmpChrMem = (unsigned char*) chrMem; 24 | bmp->bmpColMem = (unsigned char*) colMem; 25 | bmp->bmpMem = (unsigned char*) bmpMem; 26 | bmp->bmpWidth = 320; 27 | bmp->bmpHeight = 200; 28 | bmp->bmpSize = ((unsigned long) bmp->bmpWidth * bmp->bmpHeight) / 8; 29 | bmp->scrWidth = 40; 30 | bmp->scrHeight = 25; 31 | bmp->colors = 2; 32 | bmp->pixWidth = 1; 33 | bmp->bmpColSize = bmp->scrWidth * bmp->scrHeight; 34 | /* Based on NTSC */ 35 | bmp->aspectRatioMul = 3; 36 | bmp->aspectRatioDiv = 4; 37 | bmp->clearBmp = clearVicBmp; 38 | bmp->clearBmpCol = clearVicBmpCol; 39 | bmp->setPixel = setVicPix; 40 | bmp->drawLineH = drawVicLineH; 41 | bmp->drawLineV = drawVicLineV; 42 | bmp->printBmp = printVicBmp; 43 | bmp->printBmpCol = printVicBmpCol; 44 | } 45 | -------------------------------------------------------------------------------- /src/vic/init_vic_bmp_mc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Initialize bitmap struct for VIC. 12 | */ 13 | void initVicBmpMc(const bitmap *bmp, const unsigned int bmpMem, const unsigned int colMem, const unsigned int chrMem) { 14 | static unsigned char vicColors[16] = { vicBlack, vicWhite, vicRed, vicCyan, 15 | vicPurple, vicGreen, vicBlue, vicYellow, vicOrange, vicBrown, vicLightRed, 16 | vicDarkGray, vicMedGray, vicLightGreen, vicLightBlue, vicLightGray }; 17 | /* Map colors */ 18 | unsigned char i, len = sizeof(vicColors); 19 | for (i = 0; i < len; i++) { 20 | bmp->color[i] = vicColors[i]; 21 | } 22 | /* VIC bitmap configuration */ 23 | bmp->bmpChrMem = (unsigned char*) chrMem; 24 | bmp->bmpColMem = (unsigned char*) colMem; 25 | bmp->bmpMem = (unsigned char*) bmpMem; 26 | bmp->bmpWidth = 160; 27 | bmp->bmpHeight = 200; 28 | bmp->bmpSize = ((unsigned long) bmp->bmpWidth * bmp->bmpHeight) / 4; 29 | bmp->scrWidth = 40; 30 | bmp->scrHeight = 25; 31 | bmp->colors = 4; 32 | bmp->pixWidth = 2; 33 | bmp->bmpColSize = bmp->scrWidth * bmp->scrHeight; 34 | /* Based on NTSC */ 35 | bmp->aspectRatioMul = 3; 36 | bmp->aspectRatioDiv = 2; 37 | bmp->clearBmp = clearVicBmp; 38 | bmp->clearBmpCol = clearVicBmpCol; 39 | bmp->setPixel = setVicPixMc; 40 | bmp->drawLineH = drawVicLineHMc; 41 | bmp->drawLineV = drawVicLineVMc; 42 | bmp->printBmp = printVicBmp; 43 | bmp->printBmpCol = printVicBmpCol; 44 | } 45 | -------------------------------------------------------------------------------- /src/vdc/init_vdc_bmp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8563 VDC bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Initialize screen struct for VDC. 12 | */ 13 | void initVdcBmp(const bitmap *bmp, const unsigned int bmpMem, const unsigned int colMem, const unsigned char *chrMem) { 14 | static unsigned char vdcColors[16] = { vdcBlack, vdcWhite, vdcDarkRed, vdcLightCyan, 15 | vdcLightPurple, vdcDarkGreen, vdcDarkBlue, vdcLightYellow, 16 | vdcDarkPurple, vdcDarkYellow, vdcLightRed, vdcDarkCyan, vdcDarkGray, 17 | vdcLightGreen, vdcLightBlue, vdcMedGray }; 18 | /* Map colors */ 19 | unsigned char i, len = sizeof(vdcColors); 20 | for (i = 0; i < len; i++) { 21 | bmp->color[i] = vdcColors[i]; 22 | } 23 | /* VDC Screen configuration */ 24 | /* Use the alternate character set 0x0800 offset */ 25 | bmp->bmpChrMem = (unsigned char*) ((unsigned int) chrMem) + 0x0800; 26 | bmp->bmpColMem = (unsigned char*) colMem; 27 | bmp->bmpMem = (unsigned char*) bmpMem; 28 | bmp->bmpWidth = 640; 29 | bmp->bmpHeight = 200; 30 | bmp->bmpSize = ((unsigned long) bmp->bmpWidth * bmp->bmpHeight) / 8; 31 | bmp->scrWidth = 80; 32 | bmp->scrHeight = 25; 33 | bmp->colors = 2; 34 | bmp->pixWidth = 1; 35 | bmp->bmpColSize = bmp->scrWidth * bmp->scrHeight; 36 | /* Based on NTSC */ 37 | bmp->aspectRatioMul = 1; 38 | bmp->aspectRatioDiv = 2; 39 | bmp->clearBmp = clearVdcBmp; 40 | bmp->clearBmpCol = clearVdcBmpCol; 41 | bmp->setPixel = setVdcPix; 42 | bmp->drawLineH = drawVdcLineH; 43 | bmp->drawLineV = drawVdcLineV; 44 | bmp->printBmp = printVdcBmp; 45 | } 46 | -------------------------------------------------------------------------------- /src/vdc/init_vdc_int_bmp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8563 VDC bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Initialize screen struct for VIC. 12 | */ 13 | void initVdcIntBmp(const bitmap *bmp, const unsigned int bmpMem, const unsigned int colMem, const unsigned char *chrMem) { 14 | static unsigned char vdcColors[16] = { vdcBlack, vdcWhite, vdcDarkRed, vdcLightCyan, 15 | vdcLightPurple, vdcDarkGreen, vdcDarkBlue, vdcLightYellow, 16 | vdcDarkPurple, vdcDarkYellow, vdcLightRed, vdcDarkCyan, vdcDarkGray, 17 | vdcLightGreen, vdcLightBlue, vdcMedGray }; 18 | /* Map colors */ 19 | unsigned char i, len = sizeof(vdcColors); 20 | for (i = 0; i < len; i++) { 21 | bmp->color[i] = vdcColors[i]; 22 | } 23 | /* VDC Screen configuration */ 24 | /* Use the alternate character set 0x0800 offset */ 25 | bmp->bmpChrMem = (unsigned char*) ((unsigned int) chrMem) + 0x0800; 26 | bmp->bmpColMem = (unsigned char*) colMem; 27 | bmp->bmpMem = (unsigned char*) bmpMem; 28 | bmp->bmpWidth = 640; 29 | bmp->bmpHeight = 400; 30 | bmp->bmpSize = ((unsigned long) bmp->bmpWidth * bmp->bmpHeight) / 8; 31 | bmp->scrWidth = 80; 32 | bmp->scrHeight = 50; 33 | bmp->colors = 2; 34 | bmp->pixWidth = 1; 35 | bmp->bmpColSize = bmp->scrWidth * bmp->scrHeight; 36 | /* Based on NTSC */ 37 | bmp->aspectRatioMul = 5; 38 | bmp->aspectRatioDiv = 8; 39 | bmp->clearBmp = clearVdcBmp; 40 | bmp->clearBmpCol = clearVdcBmpCol; 41 | bmp->setPixel = setVdcIntPix; 42 | bmp->drawLineH = drawVdcLineH; 43 | bmp->drawLineV = drawVdcLineV; 44 | bmp->printBmp = printVdcBmp; 45 | } 46 | -------------------------------------------------------------------------------- /src/vdc/draw_vdc_line_h.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 8563 VDC bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Optimized horizontal line algorithm up to 40x faster than Bresenham. 12 | */ 13 | void drawVdcLineH(const bitmap *bmp, const unsigned int x, const unsigned int y, const unsigned int len, const unsigned char color) { 14 | static unsigned char fillTable[7] = { 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01 }; 15 | unsigned int vdcMem = (unsigned int) bmp->bmpMem; 16 | unsigned int pixByte = vdcMem + (y << 6) + (y << 4) + (x >> 3); 17 | unsigned char firstBits = x % 8; 18 | unsigned char lastBits = (x + len) % 8; 19 | unsigned int fillBytes; 20 | unsigned char fillByte; 21 | unsigned int i; 22 | if (firstBits > 0) { 23 | /* Handle left over bits on first byte */ 24 | if (color) { 25 | orVdcByte(pixByte, fillTable[firstBits - 1]); 26 | } else { 27 | andVdcByte(pixByte, ~fillTable[firstBits - 1]); 28 | } 29 | pixByte += 1; 30 | } else { 31 | outVdc(vdcUpdAddrHi, (unsigned char) (pixByte >> 8)); 32 | outVdc(vdcUpdAddrLo, (unsigned char) pixByte); 33 | } 34 | /* Do this outside loop */ 35 | if (color) { 36 | fillByte = 0xff; 37 | } else { 38 | fillByte = 0x00; 39 | } 40 | /* We only use byte fill if length > 7 pixels */ 41 | if (len > 7) { 42 | fillBytes = (len - lastBits) >> 3; 43 | for (i = 0; i < fillBytes; i++) { 44 | outVdc(vdcCPUData, fillByte); 45 | } 46 | pixByte += fillBytes; 47 | } 48 | /* Handle left over bits on last byte */ 49 | if (lastBits > 0) { 50 | if (color) { 51 | orVdcByte(pixByte, ~fillTable[lastBits - 1]); 52 | } else { 53 | andVdcByte(pixByte, fillTable[lastBits - 1]); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/vic/draw_vic_line_hmc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Optimized horizontal line algorithm for multi-color mode. 12 | */ 13 | void drawVicLineHMc(const bitmap *bmp, const unsigned int x, const unsigned int y, const unsigned int len, 14 | const unsigned char color) { 15 | // Colors 0-3 fill table 16 | static const unsigned char fillTable[4] = { 0x00, 0x55, 0xaa, 0xff }; 17 | // Colors 0-3 left fill pixels 18 | static const unsigned char leftTable[4][3] = { { 0xc0, 0xf0, 0xfc }, { 0x15, 0x05, 0x01 }, { 0x2a, 0x0a, 0x02 }, { 0x3f, 0x0f, 19 | 0x03 } }; 20 | // Colors 0-3 right fill pixels 21 | static const unsigned char rightTable[4][3] = { { 0x3f, 0x0f, 0x03 }, { 0x40, 0x50, 0x54 }, { 0x80, 0xa0, 0xa8 }, { 0xc0, 0xf0, 22 | 0xfc } }; 23 | unsigned int pixByte = bmp->scrWidth * (y & 0xf8) + (x << 1 & 0x1f8) + (y & 0x07); 24 | unsigned char firstBits = x % 4; 25 | unsigned char lastBits = (x + len) % 4; 26 | unsigned int fillBytes; 27 | unsigned char fillByte = fillTable[color]; 28 | unsigned int i; 29 | if (firstBits > 0) { 30 | // Handle left over bits on the first byte 31 | bmp->bmpMem[pixByte] |= leftTable[color][firstBits - 1]; 32 | pixByte += 8; 33 | len -= (4 - firstBits); 34 | } 35 | // We only use byte fill if length > 3 pixels 36 | if (len > 3) { 37 | fillBytes = len >> 2; // Number of full bytes to fill 38 | for (i = 0; i < fillBytes; i++) { 39 | bmp->bmpMem[pixByte] = fillByte; 40 | pixByte += 8; 41 | } 42 | } 43 | // Handle left over bits on the last byte 44 | if (lastBits > 0) { 45 | bmp->bmpMem[pixByte] |= rightTable[color][lastBits - 1]; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /scripts/sprites.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Concatnate sprite files extraxted with action replay 6. 3 | # 4 | # Since sprites are saved off with first two byte as load address we trim that off. 5 | # 6 | 7 | # Save current dir 8 | cwd=$(pwd) 9 | 10 | cd ../resources/sprites 11 | 12 | # Burwor library 13 | rm -f burwor.spr 14 | for file in bw12.prg bw11.prg bw10.prg bw09.prg bw08.prg bw07.prg bw06.prg bw05.prg bw04.prg bw03.prg bw02.prg bw01.prg; do 15 | dd if="$file" bs=1 skip=2 >> burwor.spr 16 | done 17 | 18 | # Garwor library 19 | rm -f garwor.spr 20 | for file in gw12.prg gw11.prg gw10.prg gw09.prg gw08.prg gw07.prg gw06.prg gw05.prg gw04.prg gw03.prg gw02.prg gw01.prg; do 21 | dd if="$file" bs=1 skip=2 >> garwor.spr 22 | done 23 | 24 | # Thorwor library 25 | rm -f thorwor.spr 26 | for file in tw12.prg tw11.prg tw10.prg tw09.prg tw08.prg tw07.prg tw06.prg tw05.prg tw04.prg tw03.prg tw02.prg tw01.prg; do 27 | dd if="$file" bs=1 skip=2 >> thorwor.spr 28 | done 29 | 30 | # Worrior library 31 | rm -f worrior.spr 32 | for file in w12.prg w11.prg w10.prg w09.prg w08.prg w07.prg w06.prg w05.prg w04.prg w03.prg w02.prg w01.prg; do 33 | dd if="$file" bs=1 skip=2 >> worrior.spr 34 | done 35 | 36 | # Wizard of Wor library 37 | rm -f wow.spr 38 | for file in wow12.prg wow11.prg wow10.prg wow09.prg wow08.prg wow07.prg wow06.prg wow05.prg wow04.prg wow03.prg wow02.prg wow01.prg; do 39 | dd if="$file" bs=1 skip=2 >> wow.spr 40 | done 41 | 42 | # Misc library (there's only 8 sprites, so we repeat some) 43 | rm -f worluck.spr 44 | for file in misc08.prg misc07.prg misc08.prg misc07.prg misc08.prg misc07.prg misc08.prg misc07.prg misc08.prg misc07.prg misc08.prg misc07.prg; do 45 | dd if="$file" bs=1 skip=2 >> worluck.spr 46 | done 47 | 48 | # Copy sprite libraries to resources 49 | cp *.spr ../../resources/. 50 | 51 | cd "$cwd" -------------------------------------------------------------------------------- /include/console.h: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M text console. 3 | * 4 | * Console implementation using fast text functions. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #ifndef _CONSOLE_H 10 | #define _CONSOLE_H 11 | 12 | #include 13 | #include 14 | 15 | /* 16 | * Forward reference for function pointer typedefs. 17 | */ 18 | typedef struct console console; 19 | 20 | /* 21 | * We treat the console struct like an object and encapsulate member variables and function pointers that allow polymorphism. 22 | */ 23 | typedef struct console { 24 | /* 25 | * Screen struct. 26 | */ 27 | const screen *scr; 28 | /* 29 | * Cursor X location. 30 | */ 31 | unsigned char curX; 32 | /* 33 | * Screen height in characters. 34 | */ 35 | unsigned char curY; 36 | /* 37 | * Cursor on. 38 | */ 39 | unsigned char curOn; 40 | /* 41 | * Cursor character. 42 | */ 43 | unsigned char curChar; 44 | /* 45 | * Color on. 46 | */ 47 | unsigned char colorOn; 48 | /* 49 | * Character color. 50 | */ 51 | unsigned char color; 52 | }; 53 | 54 | extern void __LIB__ initCon(const console *con, const screen *scr); 55 | extern void __LIB__ scrollCon(const console *con, const char *str); 56 | extern void __LIB__ printCon(const console *con, const char *str); 57 | extern void __LIB__ printLineCon(const console *con, const char *str); 58 | extern char __LIB__ *readLineCon(const console *con, const unsigned char len); 59 | extern unsigned int __LIB__ offsetCon(const console *con); 60 | extern void __LIB__ setCurCon(const console *con, const unsigned int offset); 61 | extern void __LIB__ printWrapCon(const console *con, const char *str); 62 | extern void __LIB__ clearHomeCon(const console *con); 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /src/app/vicgraph.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * 8564/8566 VIC-IIe bitmap demo. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #pragma output noprotectmsdos 19 | #pragma output CRT_STACK_SIZE = 1024 20 | // Protect VIC memory < 0x8000 21 | #pragma output CRT_HEAP_ADDRESS = 0xc000 22 | 23 | /* 24 | * Set VIC to MMU bank 0 or 1. 25 | */ 26 | void setVicMmuBankLocal(const unsigned char mmuRcr) { 27 | /* I/O */ 28 | outp(0x0ff00, 0x7e); 29 | /* If bank 1 then set bit 6 of RCR */ 30 | if (mmuRcr) { 31 | outp(mmuRamCfg, inp(mmuRamCfg) | 0x40); 32 | } else { 33 | outp(mmuRamCfg, inp(mmuRamCfg) & 0xbf); 34 | } 35 | /* ROM/RAM */ 36 | outp(0x0ff00, 0x7f); 37 | } 38 | 39 | /* 40 | * Copy VDC char set to memory, set screen color, MMU bank, VIC bank, screen 41 | * memory and bitmap memory. Clear bitmap memory, color memory then enable screen. 42 | */ 43 | void init(const bitmap *bmp) { 44 | initCia(); 45 | initVicBmp(bmp, 0xa000, 0x8800, 0x8000); 46 | setVicMmuBankLocal(1); 47 | initVicBmpMode(bmp, bmpBlack, bmpLightBlue, bmpWhite); 48 | } 49 | 50 | /* 51 | * Restore VIC back to CP/M defaults. 52 | */ 53 | void done() { 54 | restoreVic(); 55 | /* CPM default */ 56 | setVicMmuBankLocal(0); 57 | setVicBank(0); 58 | /* ADM-3A clear-home cursor */ 59 | putchar(0x1a); 60 | doneCia(); 61 | } 62 | 63 | /* 64 | * Run demo. 65 | */ 66 | void run(const bitmap *bmp) { 67 | runGraphDemo(bmp); 68 | } 69 | 70 | main() { 71 | /* Create bitmap struct */ 72 | bitmap *bmp = (bitmap*) malloc(sizeof(bitmap)); 73 | init(bmp); 74 | run(bmp); 75 | done(); 76 | /* Free memory */ 77 | free(bmp); 78 | } 79 | -------------------------------------------------------------------------------- /src/app/observer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * Observer pattern test. 5 | * 6 | * The observer pattern is a design pattern used to establish a one-to-many dependency between objects so that when one object (the 7 | * subject) changes state, all its dependents (observers) are notified and updated automatically. This pattern is highly useful in various 8 | * scenarios, particularly those involving dynamic relationships and decoupling components. 9 | * 10 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #pragma output noprotectmsdos 18 | #pragma output CRT_STACK_SIZE = 1024 19 | 20 | // Observer payload 21 | typedef struct { 22 | // Function to call 23 | observer o; 24 | // Data 25 | int data; 26 | } payload; 27 | 28 | /* 29 | * Update function for the payload. 30 | */ 31 | void update1(const observer *o) { 32 | // Cast to payload 33 | payload *p = (payload*) o; 34 | // Handle the update with data 35 | printf("Payload received update with data: %d\n", p->data); 36 | } 37 | 38 | /* 39 | * Update function for the payload. 40 | */ 41 | void update2(const observer *o) { 42 | // Cast to payload 43 | payload *p = (payload*) o; 44 | // Handle the update with data 45 | printf("Payload received update with data: %d\n", p->data); 46 | } 47 | 48 | int main(void) { 49 | subject s; 50 | payload observer1, observer2; 51 | // Initialize the subject 52 | subjectInit(&s); 53 | // Configure update 54 | observer1.o.update = update1; 55 | observer1.data = 1; 56 | subjectAddObserver(&s, (observer*) &observer1); 57 | observer2.o.update = update2; 58 | observer2.data = 2; 59 | subjectAddObserver(&s, (observer*) &observer2); 60 | // Notify all observers 61 | subjectNotify(&s); 62 | free(s.observers); 63 | return EXIT_SUCCESS; 64 | } 65 | -------------------------------------------------------------------------------- /src/app/vdcgrint.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * 8563 VDC bitmap demo. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "demo.h" 15 | 16 | #pragma output noprotectmsdos 17 | #pragma output CRT_STACK_SIZE = 1024 18 | 19 | /* 20 | * Configure CIA, copy fonts to memory, set screen struct for VDC and clear screen. 21 | */ 22 | void init(const bitmap *bmp, const unsigned char *chr) { 23 | initCia(); 24 | initVdcIntBmp(bmp, 0x0000, 0xc000, chr); 25 | initVdcIntBmpMode(bmp, chr, bmpBlack, bmpWhite); 26 | } 27 | 28 | /* 29 | * Restore VDC registers, screen color, screen memory and char set memory location for CP/M return. 30 | */ 31 | void done(const bitmap *bmp, const unsigned char *chr) { 32 | doneVdc(); 33 | doneCia(); 34 | /* Copy character set from memory to VDC */ 35 | copyVdcMemChr(chr, 0x2000, 512); 36 | } 37 | 38 | /* 39 | * Run demo. 40 | */ 41 | void run(const bitmap *bmp) { 42 | int i; 43 | //runGraphDemo(bmp); 44 | //drawLine(bmp, 0, 0, bmp->bmpWidth - 1, 199, bmp->color[bmpWhite]); 45 | //(bmp->setPixel)(bmp, 0, 0, bmp->color[bmpWhite]); 46 | fillVdcMem(bmp->bmpMem, 49152, 0); 47 | fillVdcMem(bmp->bmpMem + 320, 1, 255); 48 | fillVdcMem(bmp->bmpMem + 321, 1, 255); 49 | //fillVdcMem(bmp->bmpMem + 21360, 80, 255); 50 | // Debounce 51 | while (getKey(0) == 0xfd) 52 | ; 53 | while (getKey(0) != 0xfd) 54 | ; 55 | // Debounce 56 | while (getKey(0) == 0xfd) 57 | ; 58 | } 59 | 60 | main() { 61 | /* Save both VDC char sets */ 62 | unsigned char *chr = (unsigned char*) malloc(4096); 63 | /* Create screen struct */ 64 | bitmap *bmp = (bitmap*) malloc(sizeof(bitmap)); 65 | init(bmp, chr); 66 | run(bmp); 67 | done(bmp, chr); 68 | /* Free memory */ 69 | free(chr); 70 | free(bmp); 71 | } 72 | -------------------------------------------------------------------------------- /src/app/dualcon.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * C128 dual display console demo. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #pragma output noprotectmsdos 19 | #pragma output CRT_STACK_SIZE = 1024 20 | 21 | /* 22 | * Initialize key scan, VIC screen and console. 23 | */ 24 | void initVic(const console *con, const screen *scr) { 25 | /* Use ram at end of bank 1 for screen and copy VDC character set just above that */ 26 | initVicScr(scr, 0x7c00, 0x7000); 27 | initVicScrMode(scr, scrBlack, scrBlack, scrWhite); 28 | initCon(con, scr); 29 | } 30 | 31 | /* 32 | * Initialize key scan, VDC screen and console. 33 | */ 34 | void initVdc(const console *con, const screen *scr) { 35 | initVdcScr(scr, vdcScrMem, vdcColMem, vdcChrMem); 36 | initVdcScrMode(scr, scrBlack, scrBlack, scrWhite); 37 | initCon(con, scr); 38 | } 39 | 40 | /* 41 | * Restore VIC, VDC registers and CIA for CP/M return. 42 | */ 43 | void done() { 44 | doneVic(); 45 | doneVdc(); 46 | doneCia(); 47 | } 48 | 49 | /* 50 | * Run demo. 51 | */ 52 | void run(console *vicCon, console *vdcCon) { 53 | runDualDemo(vicCon, vdcCon); 54 | clearHomeCon(vicCon); 55 | clearHomeCon(vdcCon); 56 | } 57 | 58 | main() { 59 | /* Create screen structs */ 60 | screen *vicScr = (screen*) malloc(sizeof(screen)); 61 | screen *vdcScr = (screen*) malloc(sizeof(screen)); 62 | /* Create console structs */ 63 | console *vicCon = (console*) malloc(sizeof(console)); 64 | console *vdcCon = (console*) malloc(sizeof(console)); 65 | initCia(); 66 | initVic(vicCon, vicScr); 67 | initVdc(vdcCon, vdcScr); 68 | run(vicCon, vdcCon); 69 | done(); 70 | free(vicScr); 71 | free(vicCon); 72 | free(vdcScr); 73 | free(vdcCon); 74 | } 75 | -------------------------------------------------------------------------------- /src/app/vicgrmcm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * 8564/8566 VIC-IIe bitmap demo. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #pragma output noprotectmsdos 20 | #pragma output CRT_STACK_SIZE = 1024 21 | // Protect VIC memory < 0xc000 22 | #pragma output CRT_HEAP_ADDRESS = 0xc000 23 | 24 | /* 25 | * Set VIC to MMU bank 0 or 1. 26 | */ 27 | void setVicMmuBankLocal(const unsigned char mmuRcr) { 28 | /* I/O */ 29 | outp(0x0ff00, 0x7e); 30 | /* If bank 1 then set bit 6 of RCR */ 31 | if (mmuRcr) { 32 | outp(mmuRamCfg, inp(mmuRamCfg) | 0x40); 33 | } else { 34 | outp(mmuRamCfg, inp(mmuRamCfg) & 0xbf); 35 | } 36 | /* ROM/RAM */ 37 | outp(0x0ff00, 0x7f); 38 | } 39 | 40 | /* 41 | * Copy VDC char set to memory, set screen color, MMU bank, VIC bank, screen 42 | * memory and bitmap memory. Clear bitmap memory, color memory then enable screen. 43 | */ 44 | void init(const bitmap *bmp) { 45 | initCia(); 46 | initVicBmpMc(bmp, 0xa000, 0x8800, 0x8000); 47 | setVicMmuBankLocal(1); 48 | initVicBmpModeMc(bmp, bmpBlack, bmpLightBlue, bmpWhite, bmpYellow, bmpBlue); 49 | fileToMem(bmp->bmpChrMem + 256, 768, "mc.chr"); 50 | } 51 | 52 | /* 53 | * Restore VIC back to CP/M defaults. 54 | */ 55 | void done() { 56 | restoreVic(); 57 | /* CPM default */ 58 | setVicMmuBankLocal(0); 59 | setVicBank(0); 60 | /* ADM-3A clear-home cursor */ 61 | putchar(0x1a); 62 | doneCia(); 63 | } 64 | 65 | /* 66 | * Run demo. 67 | */ 68 | void run(const bitmap *bmp) { 69 | runGraphDemo(bmp); 70 | } 71 | 72 | main() { 73 | /* Create bitmap struct */ 74 | bitmap *bmp = (bitmap*) malloc(sizeof(bitmap)); 75 | init(bmp); 76 | run(bmp); 77 | done(); 78 | /* Free memory */ 79 | free(bmp); 80 | } 81 | -------------------------------------------------------------------------------- /src/vic/scroll_vic_up_asm.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Copyright (c) Steven P. Goldsmith. All rights reserved. 3 | ; 4 | ; Assembled with HI-TECH C 3.09 (CP/M-80) ZAS. 5 | ; 6 | ; Scroll VIC text memory up a line. 7 | ; 8 | 9 | SECTION code_clib 10 | PUBLIC scrollVicUpAsm 11 | PUBLIC _scrollVicUpAsm 12 | 13 | ; Return address 14 | 15 | return: 16 | 17 | defw 0 18 | 19 | ; Line length 20 | 21 | length: 22 | 23 | defw 0 24 | 25 | ; Lines 26 | 27 | lines: 28 | 29 | defw 0 30 | 31 | ; Dest line 32 | 33 | dest: 34 | 35 | defw 0 36 | 37 | scrollVicUpAsm: 38 | _scrollVicUpAsm: 39 | pop hl ; Return address? 40 | ld (return),hl ; Save return address 41 | pop de ; Lines 42 | ld (lines),de ; Save lines 43 | pop hl ; Line length 44 | ld (length),hl ; Save line length 45 | pop bc ; Dest address 46 | ld (dest),bc ; Save dest address 47 | push bc 48 | push hl 49 | push de 50 | ld hl,(return) ; Get saved return address 51 | push hl 52 | ld hl,(lines) ; Prime lines 53 | rep1: 54 | ld (lines),hl 55 | ld hl,(dest) ; hl is source 56 | ld bc,40 57 | add hl,bc ; hl = hl+bc 58 | ld de,(dest) 59 | ld bc,(length) 60 | ld a,(hl) 61 | ld (de),a 62 | inc hl 63 | inc de 64 | dec bc 65 | ldir 66 | ld hl,(dest) 67 | ld bc,40 68 | add hl,bc ; hl = hl_bc 69 | ld (dest),hl ; Save dest 70 | ld hl,(lines) 71 | dec l ; l = l-1 72 | jr nz,rep1 ; Until 0 73 | ret 74 | -------------------------------------------------------------------------------- /include/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * Common code.. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #ifndef _COMMON_H 10 | #define _COMMON_H 11 | 12 | #include 13 | 14 | /* 15 | * Forward reference. 16 | */ 17 | typedef struct node node; 18 | 19 | /* 20 | * Define the structure for a node in the doubly linked list. 21 | */ 22 | typedef struct node { 23 | // Pointer to hold the string 24 | char *data; 25 | // Pointer to the previous node 26 | struct node *prev; 27 | // Pointer to the next node 28 | struct node *next; 29 | }; 30 | 31 | /* 32 | * Forward reference. 33 | */ 34 | typedef struct observer observer; 35 | 36 | /* 37 | * Define a function pointer type for the update method that observers must implement. 38 | */ 39 | struct observer { 40 | void (*update)(const observer *o); 41 | }; 42 | 43 | /* 44 | * The subject needs to maintain a list of observers and provide methods to add, remove, and notify them. 45 | */ 46 | typedef struct { 47 | const observer **observers; 48 | int count; 49 | int capacity; 50 | } subject; 51 | 52 | extern node __LIB__* createNode(const char *data); 53 | extern void __LIB__ insertEnd(const node **head, const char *data); 54 | extern void __LIB__ freeList(const node *head); 55 | extern int __LIB__ initDir(const int login, const int user, const struct fcb *fcb, const unsigned char dmaBuf[]); 56 | extern int __LIB__ getDir(const struct fcb *fcb, const unsigned char dmaBuf[], const node *head); 57 | extern char __LIB__* fcbToFileName(const struct fcb *fcb); 58 | extern void __LIB__ fileToMem(const unsigned char *mem, const unsigned int len, const char *fileName); 59 | extern void __LIB__ subjectInit(const subject *s); 60 | extern void __LIB__ subjectAddObserver(const subject *s, const observer *o); 61 | extern void __LIB__ subjectRemoveObserver(const subject *s, const observer *o); 62 | extern void __LIB__ subjectNotify(const subject *s); 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /src/vic/draw_vic_line_h.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M 8564/8566 VIC-IIe bitmap functions. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Optimized horizontal line algorithm up to 15x faster than Bresenham. 12 | */ 13 | void drawVicLineH(const bitmap *bmp, const unsigned int x, const unsigned int y, const unsigned int len, const unsigned char color) { 14 | // Precomputed masks for bit manipulation 15 | static const unsigned char fillTable[8] = { 0x00, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01 }; 16 | // Calculate the starting byte position in the bitmap memory 17 | unsigned int pixByte = bmp->scrWidth * (y & 0xf8) + (x & 0x1f8) + (y & 0x07); 18 | // Calculate the number of bits to fill in the first and last byte 19 | unsigned char firstBits = x % 8; 20 | unsigned char lastBits = (x + len) % 8; 21 | // Number of full bytes to fill 22 | unsigned int fillBytes; 23 | unsigned int i; 24 | // Determine the fill byte based on the color (0xFF for white, 0x00 for black) 25 | unsigned char fillByte = color ? 0xff : 0x00; 26 | // Handle the first byte if it starts mid-byte 27 | if (firstBits > 0) { 28 | unsigned char mask = fillTable[firstBits]; 29 | // Set or clear the bits according to the color 30 | bmp->bmpMem[pixByte] = color ? (bmp->bmpMem[pixByte] | mask) : (bmp->bmpMem[pixByte] & ~mask); 31 | pixByte += 8; // Move to the next byte 32 | len -= 8 - firstBits; // Adjust the length to account for the handled bits 33 | } 34 | // Calculate the number of full bytes to fill 35 | fillBytes = len >> 3; 36 | // Fill the full bytes with the fill byte 37 | for (i = 0; i < fillBytes; i++) { 38 | bmp->bmpMem[pixByte] = fillByte; 39 | pixByte += 8; // Move to the next byte 40 | } 41 | // Handle the last byte if it ends mid-byte 42 | if (lastBits > 0) { 43 | unsigned char mask = ~fillTable[lastBits]; 44 | // Set or clear the bits according to the color 45 | bmp->bmpMem[pixByte] = color ? (bmp->bmpMem[pixByte] | mask) : (bmp->bmpMem[pixByte] & mask); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /scripts/phonemes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Download and convert phonemes to 8 bit snd 8000 Hz 3 | 4 | # Save current dir 5 | cwd=$(pwd) 6 | 7 | # Temp dir for downloads, etc. 8 | tmpdir="$HOME/temp" 9 | 10 | # Remove temp dir 11 | rm -rf "$tmpdir" 12 | 13 | mkdir "$tmpdir" 14 | cd "$tmpdir" 15 | 16 | # See https://github.com/radiohound/TeensyTalk 17 | url="https://github.com/radiohound/TeensyTalk/raw/main/phonemes_v3.zip" 18 | 19 | # Download zip file 20 | wget -q --directory-prefix=$tmpdir "$url" 21 | 22 | # Unzip files 23 | unzip phonemes_v3.zip 24 | 25 | # Clean up to make 39 ARPAbet phonemes 26 | rm -f V-old.wav 27 | rm -f AX.wav 28 | rm -f DX.wav 29 | mv _H.wav HH.wav 30 | rm -f IX.wav 31 | rm -f LX.wav 32 | mv J.wav JH.wav 33 | mv NX.wav NG.wav 34 | rm -f OH.wav 35 | rm -f RX.wav 36 | rm -f UL.wav 37 | rm -f UM.wav 38 | rm -f UN.wav 39 | rm -f UX.wav 40 | rm -f WH.wav 41 | rm -f YX.wav 42 | 43 | # Convert 16 bit 22050 Hz wav files to 4 bit 8000 Hz snd (raw PCM) files. 44 | for filename in *.wav; do 45 | [ -e "$filename" ] || continue 46 | name=$(basename "$filename" .wav) 47 | ffmpeg -hide_banner -loglevel error -i "$filename" -f u8 -ac 1 -ar 8000 -acodec pcm_u8 "$name.SND" 48 | # Get snd file size 49 | filesize=$(stat --format=%s "$name.SND") 50 | # Calculate 4 bit raw file size 51 | echo "$name.RAW $((filesize/2))\r" >> fileinfo.txt 52 | done 53 | 54 | # Add script to erase all snd files once converted 55 | echo "era *.SND\r" >> convert.sub 56 | echo "> convert.sub 57 | 58 | # Project root (assumes starting in scripts dir) 59 | cd "$cwd/../" 60 | 61 | # Remove existing disk image 62 | rm -f ./disks/talk.d71 63 | 64 | # Build D71 disk image for COM files 65 | cformat -2 ./disks/talk.d71 66 | 67 | # Populate disk image with sound files. 68 | ctools ./disks/talk.d71 p "$tmpdir/"*.SND 69 | ctools ./disks/talk.d71 p ./build/app/convpcm.com 70 | ctools ./disks/talk.d71 p ./build/app/playpcm.com 71 | ctools ./disks/talk.d71 p ./build/app/compile.com 72 | ctools ./disks/talk.d71 p ./build/app/voice.com 73 | ctools ./disks/talk.d71 p "$tmpdir/fileinfo.txt" 74 | # Copy resource files to app disk 75 | ctools ./disks/talk.d71 p ./resources/*.pho 76 | -------------------------------------------------------------------------------- /src/demo/keyboard.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M real time key press decode. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | /* 15 | * Display low level key scan and decoded key. 16 | * Also display joysticks and paddles. 17 | */ 18 | void keyboard(const screen *scr) { 19 | char str[40]; 20 | unsigned char exitKey, key, x1, y1, x2, y2, mx1, my1, mx2, my2; 21 | unsigned char *ciaKeyScan = (unsigned char*) malloc(11); 22 | /* Clear screen to spaces */ 23 | (scr->clearScr)(scr, 32); 24 | /* Clear color to white */ 25 | (scr->clearScrCol)(scr, scrWhite); 26 | (scr->print)(scr, (scr->scrWidth - 30) / 2, 0, "Standard and extended key scan"); 27 | (scr->printCol)(scr, (scr->scrWidth - 32) / 2, 2, scrLightBlue, " 0 1 2 3 4 5 6 7 8 9 10"); 28 | (scr->printCol)(scr, 0, 6, scrCyan, "Key pressed:"); 29 | (scr->printCol)(scr, 0, 7, scrCyan, "Joystick 1:"); 30 | (scr->printCol)(scr, 0, 8, scrCyan, "Joystick 2:"); 31 | (scr->printCol)(scr, 0, 9, scrCyan, "Paddle 1:"); 32 | (scr->printCol)(scr, 0, 10, scrCyan, "Paddle 2:"); 33 | (scr->printCol)(scr, 0, 24, scrYellow, "Press Return"); 34 | do { 35 | getKeys(ciaKeyScan); 36 | exitKey = ciaKeyScan[0]; 37 | sprintf(str, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", ciaKeyScan[0], ciaKeyScan[1], ciaKeyScan[2], 38 | ciaKeyScan[3], ciaKeyScan[4], ciaKeyScan[5], ciaKeyScan[6], ciaKeyScan[7], ciaKeyScan[8], ciaKeyScan[9], 39 | ciaKeyScan[10]); 40 | (scr->print)(scr, (scr->scrWidth - 32) / 2, 4, str); 41 | key = decodeKey(); 42 | if (key == 0) { 43 | key = 32; 44 | } 45 | sprintf(str, "%c", key); 46 | (scr->print)(scr, 13, 6, str); 47 | sprintf(str, "%02x", getJoystick1()); 48 | (scr->print)(scr, 13, 7, str); 49 | sprintf(str, "%02x", getJoystick2()); 50 | (scr->print)(scr, 13, 8, str); 51 | readSidPots(&x1, &y1, &x2, &y2); 52 | readSidMouse(&mx1, &my1, &mx2, &my2); 53 | sprintf(str, "%02x, %02x %02x, %02x", x1, y1, mx1, my1); 54 | (scr->print)(scr, 13, 9, str); 55 | sprintf(str, "%02x, %02x %02x, %02x", x2, y2, mx2, my2); 56 | (scr->print)(scr, 13, 10, str); 57 | } while (exitKey != 0xfd); 58 | free(ciaKeyScan); 59 | } 60 | -------------------------------------------------------------------------------- /src/app/textperf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * C128 text performance comparison. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | static unsigned int LINES = 23; 18 | 19 | /* 20 | * Initialize key scan, VIC screen and console. 21 | */ 22 | void initVic(const console *con, const screen *scr) { 23 | /* Use ram at end of bank 1 for screen and copy VDC character set just above that */ 24 | initVicScr(scr, 0x7c00, 0x7000); 25 | initVicScrMode(scr, scrBlack, scrBlack, scrWhite); 26 | initCon(con, scr); 27 | } 28 | 29 | /* 30 | * Initialize key scan, VDC screen and console. 31 | */ 32 | void initVdc(const console *con, const screen *scr) { 33 | initVdcScr(scr, vdcScrMem, vdcColMem, vdcChrMem); 34 | initVdcScrMode(scr, scrBlack, scrBlack, scrWhite); 35 | initCon(con, scr); 36 | } 37 | 38 | /* 39 | * Restore VIC, VDC registers and CIA for CP/M return. 40 | */ 41 | void done() { 42 | doneVic(); 43 | doneVdc(); 44 | doneCia(); 45 | } 46 | 47 | /* 48 | * Run demo. 49 | */ 50 | void run(const console *vicCon, const console *vdcCon, const unsigned int cpmPrintMs, const unsigned int cpmScrollMs, 51 | const unsigned int lines) { 52 | runTextDemo(vicCon, vdcCon, cpmPrintMs, cpmScrollMs, lines); 53 | clearHomeCon(vdcCon); 54 | clearHomeCon(vicCon); 55 | } 56 | 57 | main() { 58 | unsigned int cpmMs = cpmPrint("01234567890123456789012345678901234567890123456789012345678901234567890123456789", 23); 59 | unsigned int cpmScrollMs = cpmScroll(23); 60 | /* Program is small enough to use left over bank 1 memory */ 61 | unsigned char *vicMem = allocVicMem(1); 62 | /* Create screen structs */ 63 | screen *vicScr = (screen*) malloc(sizeof(screen)); 64 | screen *vdcScr = (screen*) malloc(sizeof(screen)); 65 | /* Create console structs */ 66 | console *vicCon = (console*) malloc(sizeof(console)); 67 | console *vdcCon = (console*) malloc(sizeof(console)); 68 | initCia(); 69 | initVic(vicCon, vicScr); 70 | initVdc(vdcCon, vdcScr); 71 | run(vicCon, vdcCon, cpmMs, cpmScrollMs, LINES); 72 | done(); 73 | free(vicScr); 74 | free(vicCon); 75 | free(vicMem); 76 | free(vdcScr); 77 | free(vdcCon); 78 | } 79 | -------------------------------------------------------------------------------- /src/app/vicsplit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * 8564/8566 VIC-IIe split screen bitmap/text demo. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #pragma output noprotectmsdos 20 | #pragma output CRT_STACK_SIZE = 1024 21 | // Protect VIC memory < 0xc000 22 | #pragma output CRT_HEAP_ADDRESS = 0xc000 23 | 24 | extern void irq1(void); 25 | 26 | /* 27 | * Initialize key scan, screen and bitmap. 28 | */ 29 | void init(const console *con, const screen *scr, const bitmap *bmp) { 30 | initCia(); 31 | /* Use ram at end of bank 1 for text and bitmap */ 32 | initVicScr(scr, 0x8800, 0x8000); 33 | initVicScrMode(scr, scrBlue, scrBlack, scrWhite); 34 | initCon(con, scr); 35 | initVicBmp(bmp, 0xa000, 0x8c00, 0x8000); 36 | /* Clear bitmap */ 37 | (bmp->clearBmp)(bmp, 0); 38 | /* Set foreground and background pixel colors */ 39 | (bmp->clearBmpCol)(bmp, (bmp->color[bmpWhite] << 4) | (bmp->color[bmpBlack] & 0x0f)); 40 | } 41 | 42 | /* 43 | * Restore VIC back to CP/M defaults. 44 | */ 45 | void done() { 46 | doneVic(); 47 | doneCia(); 48 | } 49 | 50 | /* 51 | * Find IRQ code signature and run demo. If assembler code changes then signature must change as well. 52 | */ 53 | void run(const unsigned char *memEnd, const console *con, const bitmap *bmp) { 54 | unsigned int found; 55 | unsigned char *memStart = (unsigned char*) 0x0100; 56 | /* This is the z80 signature used to find the custom interrupt code inside vicSplitScr */ 57 | static unsigned char target[] = { 0xf5, 0xc5, 0xe5, 0x01, 0x12, 0xd0 }; 58 | // Run demo using extern irq1 59 | runGraphDemoI(con, bmp, irq1); 60 | } 61 | 62 | main() { 63 | /* Use ram in bank 2 */ 64 | unsigned char *vicMem = allocVicMem(2); 65 | /* Create screen struct */ 66 | screen *scr = (screen*) malloc(sizeof(screen)); 67 | /* Create console struct */ 68 | console *con = (console*) malloc(sizeof(console)); 69 | /* Create bitmap struct */ 70 | bitmap *bmp = (bitmap*) malloc(sizeof(bitmap)); 71 | init(con, scr, bmp); 72 | run(vicMem - 1, con, bmp); 73 | done(); 74 | /* Free memory */ 75 | free(vicMem); 76 | } 77 | -------------------------------------------------------------------------------- /src/sid/pcm4.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Copyright (c) Steven P. Goldsmith. All rights reserved. 3 | ; 4 | ; Assembled with z88dk-z80asm. 5 | ; 6 | ; Play 4 bit pulse wave encoded data using SID master volume. 7 | ; 8 | ; Minimum playback rate 4 KHz 9 | ; Maximum playback rate ~19 KHz 10 | ; 11 | 12 | SECTION code_clib 13 | PUBLIC playPcm4Sid 14 | PUBLIC _playPcm4Sid 15 | 16 | playPcm4Sid: 17 | _playPcm4Sid: 18 | pop bc ; Return address? 19 | pop de ; Sample length 20 | pop hl ; Sample start address 21 | push hl 22 | push de 23 | push bc 24 | ld a,d ; Handle d having zero value 25 | or d 26 | jr nz,if1 ; d != 0? 27 | inc d ; d = d+1 28 | if1: 29 | rep1: ; Repeat 30 | ld bc,0dd0dh ; bc = CIA 2 ICR 31 | rep2: ; Repeat 32 | in a,(c) ; a = CIA 2 ICR value 33 | bit 0,a ; 34 | jr z,rep2 ; Until interrupt flag set 35 | ld a,(hl) ; a = sample byte 36 | rrca ; a = a div 16 37 | rrca ; 38 | rrca ; 39 | rrca ; 40 | and 0fh ; 4 bit nibble 41 | ld bc,0d418h ; bc = SID volume address 42 | out (c),a ; Set volume 43 | ld bc,0dd0dh ; bc = CIA 2 ICR 44 | rep3: ; Repeat 45 | in a,(c) ; a = CIA 2 ICR value 46 | bit 0,a ; 47 | jr z,rep3 ; Until interrupt flag set 48 | ld a,(hl) ; a = sample byte 49 | nop ; Delay to mimic rrca above 50 | nop 51 | nop 52 | nop 53 | and 0fh ; a = a and 15 54 | ld bc,0d418h ; bc = SID volume address 55 | out (c),a ; Set volume 56 | inc hl ; hl = hl+1 57 | dec e ; 58 | jr nz,rep1 ; 59 | dec d ; de = de-1 60 | jr nz,rep1 ; Until de = 0 61 | ret 62 | -------------------------------------------------------------------------------- /src/app/vdctest.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * 8563 VDC bitmap demo. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "demo.h" 15 | 16 | #pragma output noprotectmsdos 17 | #pragma output CRT_STACK_SIZE = 1024 18 | 19 | /* 20 | * Configure CIA, copy fonts to memory, set screen struct for VDC and clear screen. 21 | */ 22 | void init(const bitmap *bmp, const unsigned char *chr) { 23 | initCia(); 24 | saveVdc(); 25 | /* Turn off cursor for bitmap mode */ 26 | setVdcCursor(0, 0, vdcCurNone); 27 | /* Copy VDC char sets to mem bufer */ 28 | copyVdcChrMem(chr, 0x2000, 512); 29 | // Set 64K mode if not set 30 | if (!isVdc64k()) { 31 | setVdc64k(); 32 | } 33 | outVdc(vdcHzTotal, 126); 34 | outVdc(vdcHzDisp, 80); 35 | outVdc(vdcHzSyncPos, 102); 36 | outVdc(vdcVtTotal, 76); 37 | outVdc(vdcVtTotalAdj, 6); 38 | outVdc(vdcVtDisp, 76); 39 | outVdc(vdcVtSyncPos, 71); 40 | outVdc(vdcIlaceMode, 3); 41 | outVdc(vdcChTotalVt, 6); 42 | outVdc(vdcVtSmScroll, 0); 43 | outVdc(vdcHzSmScroll, 135); 44 | outVdc(vdcAddrIncPerRow, 0); 45 | /* Set bitmap mode */ 46 | setVdcFgBg(bmp->color[bmpBlack], bmp->color[bmpWhite]); 47 | setVdcAttrsOff(); 48 | setVdcBmpMode(0x000, 0xc000); 49 | //(bmp->clearBmpCol)(bmp, (bmp->color[bmpWhite])); 50 | //(bmp->clearBmp)(bmp, 0); 51 | } 52 | 53 | /* 54 | * Restore VDC registers, screen color, screen memory and char set memory location for CP/M return. 55 | */ 56 | void done(const bitmap *bmp, const unsigned char *chr) { 57 | doneVdc(); 58 | doneCia(); 59 | /* Copy character set from memory to VDC */ 60 | copyVdcMemChr(chr, 0x2000, 512); 61 | } 62 | 63 | /* 64 | * Run demo. 65 | */ 66 | void run() { 67 | int i; 68 | //runGraphDemo(bmp); 69 | //drawLine(bmp, 0, 0, bmp->bmpWidth - 1, 199, bmp->color[bmpWhite]); 70 | //(bmp->setPixel)(bmp, 0, 0, bmp->color[bmpWhite]); 71 | fillVdcMem(0x0000, 49152, 0); 72 | fillVdcMem(0x000 + 320, 1, 255); 73 | fillVdcMem(0x000 + 321, 1, 255); 74 | // Debounce 75 | while (getKey(0) == 0xfd) 76 | ; 77 | while (getKey(0) != 0xfd) 78 | ; 79 | // Debounce 80 | while (getKey(0) == 0xfd) 81 | ; 82 | } 83 | 84 | main() { 85 | /* Save both VDC char sets */ 86 | unsigned char *chr = (unsigned char*) malloc(4096); 87 | init(chr); 88 | run(); 89 | done(chr); 90 | /* Free memory */ 91 | free(chr); 92 | } 93 | -------------------------------------------------------------------------------- /src/demo/run_dual_demo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M console. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | /* 14 | * Generate random sentences on both VIC and VDC, 15 | */ 16 | void dualRandSentence(const console *vicCon, const console *vdcCon, const unsigned char sentences, unsigned char color) { 17 | static unsigned char colors[] = { scrGreen, scrLightGreen, scrBlue, scrLightBlue, 18 | scrRed, scrLightRed }; 19 | unsigned char i; 20 | char *str; 21 | if (color) { 22 | vicCon->colorOn = 1; 23 | vdcCon->colorOn = 1; 24 | } else { 25 | vicCon->colorOn = 0; 26 | vdcCon->colorOn = 0; 27 | } 28 | // Use VIC raster to initialize random number 29 | srand(inp(vicRaster)); 30 | for (i = 0; i < sentences; i++) { 31 | if (color) { 32 | vicCon->color = colors[rand() % (sizeof(colors) / sizeof(colors[0]))]; 33 | vdcCon->color = colors[rand() % (sizeof(colors) / sizeof(colors[0]))]; 34 | } 35 | str = generateSentence(); 36 | printWrapCon(vicCon, str); 37 | free(str); 38 | if (vicCon->curX != 0) { 39 | printCon(vicCon, " "); 40 | } 41 | str = generateSentence(); 42 | printWrapCon(vdcCon, str); 43 | free(str); 44 | if (vdcCon->curX != 0) { 45 | printCon(vdcCon, " "); 46 | } 47 | } 48 | printLineCon(vicCon, ""); 49 | printLineCon(vdcCon, ""); 50 | } 51 | 52 | /* 53 | * Display color mappings VIC and VDC, 54 | */ 55 | void dualColors(const console *vicCon, const console *vdcCon) { 56 | static char *colorNames[16][1] = { { "scrBlack" }, { "scrWhite" }, { "scrRed" }, { "scrCyan" }, { "scrPurple" }, { "scrGreen" }, 57 | { "scrBlue" }, { "scrYellow" }, { "scrOrange" }, { "scrBrown" }, { "scrLightRed" }, { "scrDarkGray" }, { "scrMedGray" }, 58 | { "scrLightGreen" }, { "scrLightBlue" }, { "scrLightGray" } }; 59 | unsigned char i; 60 | vicCon->colorOn = 1; 61 | vdcCon->colorOn = 1; 62 | for (i = 0; i < 16; i++) { 63 | vicCon->color = i; 64 | printLineCon(vicCon, colorNames[i][0]); 65 | vdcCon->color = i; 66 | printLineCon(vdcCon, colorNames[i][0]); 67 | } 68 | } 69 | 70 | /* 71 | * Run demo. 72 | */ 73 | void runDualDemo(const console *vicCon, const console *vdcCon) { 74 | dualRandSentence(vicCon, vdcCon, 100, 0); 75 | dualRandSentence(vicCon, vdcCon, 100, 1); 76 | waitKey(vicCon->scr); 77 | clearHomeCon(vicCon); 78 | clearHomeCon(vdcCon); 79 | dualColors(vicCon, vdcCon); 80 | waitKey(vicCon->scr); 81 | } 82 | -------------------------------------------------------------------------------- /src/sid/pcm2.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Copyright (c) Steven P. Goldsmith. All rights reserved. 3 | ; 4 | ; Assembled with z88dk-z80asm. 5 | ; 6 | ; Play 2 bit pulse wave encoded data using SID master volume. 7 | ; 8 | ; Minimum playback rate 4 KHz 9 | ; Maximum playback rate ~15 KHz 10 | ; 11 | 12 | SECTION code_clib 13 | PUBLIC playPcm2Sid 14 | PUBLIC _playPcm2Sid 15 | 16 | start: 17 | 18 | defw 0 19 | 20 | playPcm2Sid: 21 | _playPcm2Sid: 22 | pop hl ; Return address 23 | pop de ; Sample length 24 | pop bc ; Sample start address 25 | ld (start), bc ; Save sample start address 26 | push bc 27 | push de 28 | push hl 29 | push ix ; Preserve ix 30 | ex de,hl ; Swap de and hl (sample length) 31 | ld a,h ; Handle h having zero value 32 | or h 33 | jr nz,if1 ; h != 0? 34 | inc h ; h = h+1 35 | if1: 36 | ld ix,(start) 37 | rep1: ; Repeat 38 | ld d,(ix+0) ; d = Sample byte 39 | ld e,04h ; e = 4 bit pairs to count 40 | rep2: ; Repeat 41 | ld bc,0dd0dh ; bc = CIA 2 ICR 42 | rep3: ; Repeat 43 | in a,(c) ; a = CIA 2 ICR value 44 | bit 0,a ; a = 0 45 | jr z,rep3 ; Until interrupt flag set 46 | ld a,00h ; a = 0 47 | rlc d ; Get first sample bit 48 | rla ; Shift carry bit to a 49 | rlc d ; Get second sample bit 50 | rla ; Shift carry bit to a 51 | rla ; a = a*2 52 | rla ; a = a*2 53 | add a,3 ; a = a+3 54 | ld bc,0d418h ; bc = SID volume address 55 | out (c),a ; Set volume 56 | dec e ; e = e-1 57 | jr nz,rep2 ; Until e = 0 58 | inc ix ; ix = ix+1 59 | dec l ; l = l-1 60 | jr nz,rep1 ; Until l = 0 61 | dec h ; h = h-1 62 | jr nz,rep1 ; Until h = 0 63 | pop ix ; Restore ix 64 | ret 65 | -------------------------------------------------------------------------------- /src/app/siddemo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M C Library C3L 3 | * 4 | * C128 6581/8580 SID demo. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | * 8 | */ 9 | 10 | #pragma output noprotectmsdos 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | /* 18 | * MS delay up to 65535. 19 | */ 20 | void delay(const unsigned int ms) { 21 | /* Timer A counts milliseconds */ 22 | startTimerAB(cia2, ciaMs, ms, ciaCountA); 23 | outp(cia2 + ciaCtrlRegA, ciaCpuCont); 24 | /* Wait for ICR flag */ 25 | while ((inp(cia2+ciaIcr) & 0x02) == 0) 26 | ; 27 | } 28 | 29 | /* 30 | * Plane sound. 31 | */ 32 | void planeSound() { 33 | unsigned int pulse; 34 | unsigned int freq = 2047; 35 | setSidVol(15, 0); 36 | setSidEnv(sidVoice1, 12, 10, 0, 0); 37 | setSidAtt(sidVoice1, sidSqu); 38 | for (pulse = 0; pulse < 3840; pulse += 10) { 39 | setSidPulWav(sidVoice1, pulse); 40 | setSidFreq(sidVoice1, freq); 41 | freq -= 5; 42 | delay(2); 43 | } 44 | setSidRel(sidVoice1, sidSqu); 45 | delay(6); 46 | setSidFreq(sidVoice1, 0); 47 | } 48 | 49 | /* 50 | * Tommy gun sound. 51 | */ 52 | void tommyGunSound() { 53 | unsigned char i; 54 | setSidVol(15, 0); 55 | for (i = 0; i < 20; i++) { 56 | setSidEnv(sidVoice1, 0, 3, 0, 0); 57 | setSidFreq(sidVoice1, 5360); 58 | setSidAtt(sidVoice1, sidNoi); 59 | delay(100); 60 | setSidRel(sidVoice1, sidNoi); 61 | delay(6); 62 | } 63 | setSidFreq(sidVoice1, 0); 64 | } 65 | 66 | /* 67 | * Explode sound. 68 | */ 69 | void explodeSound() { 70 | setSidVol(15, 0); 71 | setSidEnv(sidVoice1, 0, 0, 15, 11); 72 | setSidFreq(sidVoice1, 200); 73 | setSidAtt(sidVoice1, sidNoi); 74 | delay(8); 75 | setSidRel(sidVoice1, sidNoi); 76 | delay(2400); 77 | setSidFreq(sidVoice1, 0); 78 | } 79 | 80 | /* 81 | * Bomb drop sound. 82 | */ 83 | void bombDropSound() { 84 | unsigned short i; 85 | setSidVol(15, 0); 86 | setSidEnv(sidVoice3, 13, 0, 15, 0); 87 | setSidFreq(sidVoice3, 0); 88 | setSidAtt(sidVoice3, sidTri); 89 | for (i = 32000; i > 200; i -= 200) { 90 | setSidFreq(sidVoice3, i); 91 | delay(18); 92 | } 93 | setSidRel(sidVoice3, sidTri); 94 | delay(6); 95 | setSidFreq(sidVoice3, 0); 96 | } 97 | 98 | main() { 99 | initCia(); 100 | printf("\nPlane\n"); 101 | planeSound(); 102 | printf("Tommy gun\n"); 103 | tommyGunSound(); 104 | printf("Bomb drop\n"); 105 | bombDropSound(); 106 | printf("Explode\n"); 107 | explodeSound(); 108 | setSidVol(0, 0); 109 | doneCia(); 110 | } 111 | -------------------------------------------------------------------------------- /src/console/read_line_con.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M console read line. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | /* 13 | * Handle backspace for editing. 14 | */ 15 | void backSpace(const console *con) { 16 | unsigned int scrOfs = offsetCon(con) - 1; 17 | char printBuf[3]; 18 | printBuf[0] = con->curChar; 19 | printBuf[1] = ' '; 20 | printBuf[2] = 0; 21 | /* Calculate cursor position for backspace */ 22 | setCurCon(con, scrOfs); 23 | con->curOn = 0; 24 | printCon(con, printBuf); 25 | con->curOn = 1; 26 | /* Calculate new cursor position */ 27 | setCurCon(con, scrOfs); 28 | } 29 | 30 | /* 31 | * Use screen memory as simple input line. Only backspace supported, but insert 32 | * and delete could be added later. 33 | */ 34 | char* readLineCon(const console *con, unsigned char len) { 35 | screen *scr = con->scr; 36 | char *str, printBuf[2]; 37 | unsigned char strLen = 0, keyVal, lastKeyVal = 0, curOn = con->curOn, i; 38 | printBuf[1] = 0; 39 | /* Make sure cursor is on for input */ 40 | con->curOn = 1; 41 | printBuf[0] = con->curChar; 42 | (scr->print)(scr, con->curX, con->curY, printBuf); 43 | /* Timer A counts milliseconds 48 times or ~1/20 second */ 44 | startTimerAB(cia2, ciaMs, 48, ciaCountA); 45 | /* Start timer in continuous mode */ 46 | outp(cia2+ciaCtrlRegA, ciaCpuCont); 47 | do { 48 | keyVal = decodeKey(); 49 | /* Debounce if current key equals last key */ 50 | if (keyVal == lastKeyVal) { 51 | i = 0; 52 | do { 53 | /* Wait for underflow of ciaTimerBHi */ 54 | while ((inp(cia2+ciaIcr) & 0x02) == 0x00) 55 | ; 56 | keyVal = decodeKey(); 57 | i++; 58 | } while ((keyVal == lastKeyVal) && (i < 3)); 59 | } 60 | lastKeyVal = keyVal; 61 | /* Decoded key? */ 62 | if (keyVal != 0x00) { 63 | /* Backspace? */ 64 | if (keyVal == 0x7f) { 65 | if (strLen > 0) { 66 | strLen--; 67 | backSpace(con); 68 | } 69 | } else { 70 | if (keyVal != 0x0d && strLen < len) { 71 | strLen++; 72 | printBuf[0] = keyVal; 73 | printCon(con, printBuf); 74 | } 75 | } 76 | } 77 | } while (keyVal != 0x0d); 78 | /* Stop timer */ 79 | outp(cia2+ciaCtrlRegA, ciaStopTimer); 80 | str = (char*) malloc(strLen + 1); 81 | /* Screen to string */ 82 | (scr->copyScrToStr)(scr, (con->curY * scr->scrWidth) + con->curX - strLen, str, strLen); 83 | /* Remove cursor from end of input */ 84 | (scr->print)(scr, con->curX, con->curY, " "); 85 | con->curOn = curOn; 86 | return str; 87 | } 88 | -------------------------------------------------------------------------------- /src/vic/scroll_vic_up_col_asm.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Copyright (c) Steven P. Goldsmith. All rights reserved. 3 | ; 4 | ; Assembled with HI-TECH C 3.09 (CP/M-80) ZAS. 5 | ; 6 | ; Scroll VIC color memory up a line. 7 | ; 8 | 9 | SECTION code_clib 10 | PUBLIC scrollVicUpColAsm 11 | PUBLIC _scrollVicUpColAsm 12 | 13 | ; Return address 14 | 15 | return: 16 | 17 | defw 0 18 | 19 | ; Line length 20 | 21 | length: 22 | 23 | defw 0 24 | 25 | ; Source line 26 | 27 | source: 28 | 29 | defw 0 30 | 31 | ; Dest line 32 | 33 | dest: 34 | 35 | defw 0 36 | 37 | ; Line buffer to hold input line for output 38 | 39 | buffer: 40 | 41 | defs 40 42 | 43 | scrollVicUpColAsm: 44 | _scrollVicUpColAsm: 45 | pop hl ; Return address 46 | ld (return),hl ; Save return address 47 | pop de ; Lines in e 48 | pop hl ; Line length 49 | ld (length),hl ; Save line length 50 | pop bc ; Dest port 51 | ld (dest),bc ; Save dest 52 | push bc 53 | push hl 54 | push de 55 | ld d,l ; Line length in d 56 | ld hl,(return) ; Get saved return address 57 | push hl 58 | ld hl,(dest) 59 | rep1: 60 | ld bc,40 61 | add hl,bc ; hl = hl_bc 62 | ld (source),hl ; Save source 63 | ld bc,(source) ; bc = source 64 | ld hl,buffer ; hl = buffer address 65 | rep2: 66 | in a,(c) ; Get color byte 67 | ld (hl),a ; Save in buffer 68 | inc hl ; hl = hl+1 69 | inc bc ; bc = bc+1 70 | dec d ; d = d-1 71 | jr nz,rep2 ; Until 0 72 | ld hl,(length) ; hl = length 73 | ld d,l ; d = l 74 | ld bc,(dest) ; bc = dest 75 | ld hl,buffer ; hl = buffer address 76 | rep3: 77 | ld a,(hl) ; a = buffer byte 78 | out (c),a ; set color byte 79 | inc hl ; hl = hl+1 80 | inc bc ; bc = bc+1 81 | dec d ; d = d-1 82 | jr nz,rep3 ; Until 0 83 | ld hl,(length) ; hl = length 84 | ld d,l ; d = l 85 | ld hl,(source) ; hl = source 86 | ld (dest),hl ; Save dest 87 | dec e ; e = e-1 88 | jr nz,rep1 ; Until 0 89 | ret 90 | -------------------------------------------------------------------------------- /src/sid/pcm1.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Copyright (c) Steven P. Goldsmith. All rights reserved. 3 | ; 4 | ; Assembled with z88dk-z80asm. 5 | ; 6 | ; Play 1 bit pulse wave encoded data using SID master volume. 7 | ; 8 | ; Minimum playback rate 4 KHz 9 | ; Maximum playback rate ~18 KHz 10 | ; 11 | 12 | SECTION code_clib 13 | PUBLIC playPcm1Sid 14 | PUBLIC _playPcm1Sid 15 | 16 | ; Return address 17 | 18 | return: 19 | 20 | defw 0 21 | 22 | ; Sample amplitude can be 1 - 15 23 | 24 | amp: 25 | 26 | defw 0 27 | 28 | start: 29 | 30 | defw 0 31 | 32 | playPcm1Sid: 33 | _playPcm1Sid: 34 | pop hl ; Return address? 35 | ld (return),hl ; Save return address 36 | pop hl ; Sample amplitude 37 | ld (amp),hl ; Save sample amplitude 38 | pop de ; Sample length 39 | pop bc ; Sample start address 40 | ld (start), bc ; Save sample start address 41 | push bc 42 | push de 43 | ld (amp),hl ; Save sample amplitude 44 | push hl 45 | ld hl,(return) ; Get saved return address 46 | push hl 47 | push ix ; Preserve ix 48 | ex de,hl ; Swap de and hl (sample length) 49 | ld a,h ; Handle h having zero value 50 | or h 51 | jr nz,if1 ; h != 0? 52 | inc h ; h = h+1 53 | if1: 54 | ld ix,(start) 55 | rep1: ; Repeat 56 | ld d,(ix+0) ; d = Sample byte 57 | ld e,08h ; e = 8 bits to count 58 | rep2: 59 | ld bc,0dd0dh ; bc = CIA 2 ICR 60 | rep3: ; Repeat 61 | in a,(c) ; a = CIA 2 ICR value 62 | bit 0,a ; 63 | jr z,rep3 ; Until interrupt flag set 64 | ld a,00h ; a = volume for 0 bits 65 | rlc d ; Set sample bit 66 | jr nc,endif1 ; if carry=1 then 67 | ld a,(amp) ; a = volume for 1 bits 68 | endif1: 69 | ld bc,0d418h ; bc = SID volume address 70 | out (c),a ; Set volume 71 | dec e ; e = e-1 72 | jr nz,rep2 ; Until e = 0 73 | inc ix ; ix = ix+1 74 | dec l ; l = l-1 75 | jr nz,rep1 ; Until l = 0 76 | dec h ; h = h-1 77 | jr nz,rep1 ; Until h = 0 78 | pop ix ; Restore ix 79 | ret 80 | -------------------------------------------------------------------------------- /include/sid.h: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6581/8580 SID. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #ifndef _SID_H 8 | #define _SID_H 9 | 10 | #include 11 | 12 | #define sidVoice1 0xd400 /* Voices */ 13 | #define sidVoice2 0xd407 14 | #define sidVoice3 0xd40E 15 | #define sidCutoffLo 0xd415 /* Cutoff filter */ 16 | #define sidCutoffHi 0xd416 17 | #define sidResCtrl 0xd417 /* Resonance control */ 18 | #define sidVolume 0xd418 /* Master volume and filter select */ 19 | #define sidPotX 0xd419 /* Paddle X */ 20 | #define sidPotY 0xd41A /* Paddle Y */ 21 | #define sidEnvGen3 0xd41C 22 | 23 | #define sidGate 0x01 /* Waveforms */ 24 | #define sidSync 0x02 25 | #define sidRing 0x04 26 | #define sidTest 0x08 27 | #define sidTri 0x10 28 | #define sidSaw 0x20 29 | #define sidSqu 0x40 30 | #define sidNoi 0x80 31 | 32 | #define sidLowPass 0x10 /* Filter select settings */ 33 | #define sidBandPass 0x20 34 | #define sidHighPass 0x40 35 | #define sidVoice3Off 0x80 36 | 37 | #define sidFilter1 0x01 /* Filter resonance output settings */ 38 | #define sidFilter2 0x02 39 | #define sidFilter3 0x04 40 | #define sidFilterExt 0x08 41 | 42 | /* 43 | * Official ARPAbet has 39 phonemes 44 | */ 45 | #define PHONEMES 39 46 | 47 | typedef char arpabetName[PHONEMES][3]; 48 | 49 | /* 50 | * Forward reference. 51 | */ 52 | typedef struct phonemes phonemes; 53 | 54 | /* 55 | * Output file header. 56 | */ 57 | typedef struct phonemes { 58 | /* 59 | * Play back Hz. 60 | */ 61 | unsigned int hz; 62 | /* 63 | * Sample width in bits. 64 | */ 65 | unsigned char bits; 66 | /* 67 | * ARPAbet name 68 | */ 69 | arpabetName name; 70 | /* 71 | * Phoneme length. 72 | */ 73 | unsigned int arpabetLen[PHONEMES]; 74 | }; 75 | 76 | extern void __LIB__ clearSid(); 77 | extern void __LIB__ setSidVol(const unsigned char amp, const unsigned char filter); 78 | extern void __LIB__ setSidEnv(const unsigned int voice, const unsigned char attack, const unsigned char decay, const unsigned char sustain, 79 | const unsigned char release); 80 | extern void __LIB__ setSidRel(const unsigned int voice, const unsigned char waveform); 81 | extern void __LIB__ setSidFreq(const unsigned int voice, const unsigned int freq); 82 | extern void __LIB__ setSidAtt(const unsigned int voice, const unsigned char waveform); 83 | extern void __LIB__ setSidPulWav(const unsigned int voice, const unsigned int width); 84 | extern void __LIB__ readSidPots(const unsigned char *x1, const unsigned char *y1, const unsigned char *x2, const unsigned char *y2); 85 | extern void __LIB__ readSidMouse(const unsigned char *x1, const unsigned char *y1, const unsigned char *x2, const unsigned char *y2); 86 | extern void __LIB__ playPcm1Sid(const unsigned char *buffer, const unsigned int len, const unsigned char vol) __smallc; 87 | extern void __LIB__ playPcm2Sid(const unsigned char *buffer, const unsigned int len) __smallc; 88 | extern void __LIB__ playPcm4Sid(const unsigned char *buffer, const unsigned int len) __smallc; 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /include/screen.h: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 CP/M text abstraction. 3 | * 4 | * Screen abstraction uses function pointers to drive output, thus the 5 | * same code will work on the VIC and VDC. This will also allow for virtual 6 | * screens, page flipping, etc. 7 | * 8 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 9 | */ 10 | 11 | #ifndef _SCREEN_H 12 | #define _SCREEN_H 13 | 14 | #include 15 | 16 | /* Generic color mapping */ 17 | #define scrBlack 0 18 | #define scrWhite 1 19 | #define scrRed 2 20 | #define scrCyan 3 21 | #define scrPurple 4 22 | #define scrGreen 5 23 | #define scrBlue 6 24 | #define scrYellow 7 25 | #define scrOrange 8 26 | #define scrBrown 9 27 | #define scrLightRed 10 28 | #define scrDarkGray 11 29 | #define scrMedGray 12 30 | #define scrLightGreen 13 31 | #define scrLightBlue 14 32 | #define scrLightGray 15 33 | 34 | /* 35 | * Forward reference for function pointer typedefs. 36 | */ 37 | typedef struct screen screen; 38 | 39 | /* 40 | * General function pointers. 41 | */ 42 | typedef void (*fillMemPtr)(const unsigned char*, const unsigned int, const unsigned char); 43 | 44 | /* 45 | * Text function pointers. 46 | */ 47 | typedef void (*clearScrPtr)(const screen*, const unsigned char); 48 | typedef void (*clearScrColPtr)(const screen*, const unsigned char); 49 | typedef void (*printPtr)(const screen*, const unsigned char, const unsigned char, const char*); 50 | typedef void (*printColPtr)(const screen*, const unsigned char, const unsigned char, const unsigned char, const char*); 51 | typedef void (*scrollUpPtr)(const screen*, const unsigned char, const unsigned char, const unsigned char, const unsigned char); 52 | typedef void (*scrollUpColPtr)(const screen*, const unsigned char, const unsigned char, const unsigned char, const unsigned char); 53 | typedef void (*copyScrToStrPtr)(const screen*, const unsigned int, const char*, const unsigned int); 54 | 55 | /* 56 | * We treat the screen struct like an object and encapsulate member variables and function pointers that allow polymorphism. 57 | */ 58 | typedef struct screen { 59 | /* 60 | * Color mapping 61 | */ 62 | unsigned char color[16]; 63 | /* 64 | * Screen width in characters. 65 | */ 66 | unsigned char scrWidth; 67 | /* 68 | * Screen height in characters. 69 | */ 70 | unsigned char scrHeight; 71 | /* 72 | * Screen size in bytes. 73 | */ 74 | unsigned int scrSize; 75 | /* 76 | * Screen memory location. 77 | */ 78 | unsigned char *scrMem; 79 | /* 80 | * Screen color location. 81 | */ 82 | unsigned char *scrColMem; 83 | /* 84 | * Character set location. 85 | */ 86 | unsigned char *chrMem; 87 | /* 88 | * Fill memory with unsigned char. 89 | */ 90 | fillMemPtr fillMem; 91 | /* 92 | * Clear screen. 93 | */ 94 | clearScrPtr clearScr; 95 | /* 96 | * Clear screen color. 97 | */ 98 | clearScrColPtr clearScrCol; 99 | /* 100 | * Print text without color. 101 | */ 102 | printPtr print; 103 | /* 104 | * Print text with color. 105 | */ 106 | printColPtr printCol; 107 | /* 108 | * Scroll text up one line. 109 | */ 110 | scrollUpPtr scrollUp; 111 | /* 112 | * Scroll text color one line. 113 | */ 114 | scrollUpColPtr scrollUpCol; 115 | /* 116 | * Copy text from screen to string. 117 | */ 118 | copyScrToStrPtr copyScrToStr; 119 | }; 120 | 121 | extern void __LIB__ asciiToPet(const char *str); 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /src/cia/decode_key.c: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6526 CIA functions. 3 | * 4 | * Keys are mapped the same as getch for the most part. 5 | * 6 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | * Decode key from getKeys array. Handle shifted and unshifted keys. 0x00 is 14 | * returned if no keys pressed, unmapped keys pressed or unable to decode. 15 | */ 16 | unsigned char decodeKey() { 17 | // Key to ASCII code unshifted. Unmapped keys are set to 0x00. 18 | static unsigned char stdKeys[11][8] = { { 0x7f, 0x0d, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18 }, { '3', 'w', 'a', '4', 'z', 's', 'e', 19 | 0x00 }, { '5', 'r', 'd', '6', 'c', 'f', 't', 'x' }, { '7', 'y', 'g', '8', 'b', 'h', 'u', 'v' }, { '9', 'i', 'j', '0', 20 | 'm', 'k', 'o', 'n' }, { '+', 'p', 'l', '-', '.', ':', '@', ',' }, { '\\', '*', ';', 0x00, 0x00, '=', '^', '/' }, { '1', 21 | 0x00, 0x00, '2', 0x20, 0x00, 'q', 0x00 }, { 0x00, '8', '5', 0x09, '2', '4', '7', '1' }, { 0x1b, '+', '-', 0x0a, 0x0d, 22 | '6', '9', '3' }, { 0x00, '0', '.', 0x05, 0x18, 0x13, 0x04, 0x00 } }; 23 | 24 | // Key to ASCII code shifted. Unmapped keys are set to 0x00. 25 | static unsigned char shiftKeys[11][8] = { { 0x7f, 0x0d, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18 }, { '#', 'W', 'A', '$', 'Z', 'S', 26 | 'E', 0x00 }, { '%', 'R', 'D', '&', 'C', 'F', 'T', 'X' }, { '\'', 'Y', 'G', '(', 'B', 'H', 'U', 'V' }, { ')', 'I', 'J', 27 | '0', 'M', 'K', 'O', 'N' }, { '+', 'P', 'L', '-', '>', '[', '@', '<' }, { '\\', '*', ']', 0x00, 0x00, '=', '^', '?' }, { 28 | '!', 0x00, 0x00, '"', 0x20, 0x00, 'Q', 0x00 }, { 0x00, '8', '5', 0x09, '2', '4', '7', '1' }, { 0x1b, '+', '-', 0x0a, 29 | 0x0d, '6', '9', '3' }, { 0x00, '0', '.', 0x05, 0x18, 0x13, 0x04, 0x00 } }; 30 | unsigned char i = 0; 31 | unsigned char keyCode = 0x00; 32 | unsigned char lsCol, rsCol, col; 33 | unsigned char *ciaKeyScan = (unsigned char*) malloc(11); 34 | getKeys(ciaKeyScan); 35 | // Shift row pressed? 36 | if ((ciaKeyScan[1] != 0xff) || (ciaKeyScan[6] != 0xff)) { 37 | lsCol = getLsKeyCol(ciaKeyScan[1]); 38 | rsCol = getRsKeyCol(ciaKeyScan[6]); 39 | /* Left shift plus key in same row? */ 40 | if (lsCol < 7) { 41 | keyCode = shiftKeys[1][lsCol]; 42 | // Right shift plus key in same row? 43 | } else if ((rsCol < 8) && (rsCol != 4)) { 44 | keyCode = shiftKeys[6][rsCol]; 45 | // Only shift pressed? 46 | } else if ((ciaKeyScan[1] == 0x7f) || (ciaKeyScan[6] == 0xef)) { 47 | // Find first key row 48 | while ((i < 11) && (ciaKeyScan[i] == 0xff)) { 49 | // Skip left shift or right shift if pressed by themselves 50 | if (((i == 0) && (ciaKeyScan[1] == 0x7f)) || ((i == 5) && ciaKeyScan[6] == 0xef)) { 51 | i++; 52 | } 53 | i++; 54 | } 55 | // Another key pressed besides shift? 56 | if (i < 11) { 57 | col = getKeyCol(ciaKeyScan[i]); 58 | /* Make sure key code is valid */ 59 | if (col < 8) { 60 | keyCode = shiftKeys[i][col]; 61 | } 62 | } 63 | // Row 1 not pressed? 64 | } else if (ciaKeyScan[1] == 0xff) { 65 | col = getKeyCol(ciaKeyScan[6]); 66 | /* Make sure key code is valid */ 67 | if (col < 8) { 68 | keyCode = stdKeys[6][col]; 69 | } 70 | } else { 71 | // Row 1 pressed 72 | col = getKeyCol(ciaKeyScan[1]); 73 | // Make sure key code is valid 74 | if (col < 8) { 75 | keyCode = stdKeys[1][col]; 76 | } 77 | } 78 | } else { 79 | // No shift rows pressed, so find first key row 80 | while ((i < 11) && (ciaKeyScan[i] == 0xff)) { 81 | i++; 82 | } 83 | if (i < 11) { 84 | col = getKeyCol(ciaKeyScan[i]); 85 | // Make sure key code is valid 86 | if (col < 8) { 87 | keyCode = stdKeys[i][col]; 88 | } 89 | } 90 | } 91 | free(ciaKeyScan); 92 | return keyCode; 93 | } 94 | -------------------------------------------------------------------------------- /include/cia.h: -------------------------------------------------------------------------------- 1 | /* 2 | * C128 6526 CIA. 3 | * 4 | * Copyright (c) Steven P. Goldsmith. All rights reserved. 5 | */ 6 | 7 | #ifndef _CIA_H 8 | #define _CIA_H 9 | 10 | #include 11 | 12 | #define cia1 0xdc00 /* Complex interface adapter #1 */ 13 | #define cia2 0xdd00 /* Complex interface adapter #2 */ 14 | 15 | #define ciaDataA 0x00 /* Port A data I/O register */ 16 | #define ciaDataB 0x01 /* Port B data I/O register */ 17 | #define ciaDdrA 0x02 /* Port A data direction register */ 18 | #define ciaDdrB 0x03 /* Port B data direction register */ 19 | #define ciaTimerALo 0x04 /* Timer A latch/counter (low byte) */ 20 | #define ciaTimerAHi 0x05 /* Timer A latch/counter (high byte) */ 21 | #define ciaTimerBLo 0x06 /* Timer B latch/counter (low byte) */ 22 | #define ciaTimerBHi 0x07 /* Timer B latch/counter (high byte) */ 23 | #define ciaTodTen 0x08 /* Time-of-day clock (1/10 seconds) */ 24 | #define ciaTodSec 0x09 /* Time-of-day clock (seconds) */ 25 | #define ciaTodMin 0x0a /* Time-of-day clock (minutes) */ 26 | #define ciaTodHrs 0x0b /* Time-of-day clock (hours) */ 27 | #define ciaSerial 0x0c /* Serial data register */ 28 | #define ciaIcr 0x0d /* Interrupt control register */ 29 | #define ciaCtrlRegA 0x0e /* Control register A */ 30 | #define ciaCtrlRegB 0x0f /* Control register B */ 31 | 32 | #define vicExtKey 0xd02f /* Extended keyboard scan register on the VIC */ 33 | 34 | #define ciaTimerFreq 1022730L /* CIA timer freq */ 35 | #define ciaEnableIrq 0x82 /* Enable cia irq */ 36 | #define ciaClearIcr 0x7f /* Clear all cia irq enable bits */ 37 | #define ciaPots 0xc0 /* Set bits 6 and 7 to output */ 38 | #define ciaCpuCont 0x11 /* Load latch, start timer, count cpu cycles continuous */ 39 | #define ciaCpuOne 0x19 /* Load latch, start timer, count cpu cycles one shot */ 40 | #define ciaCountA 0x51 /* Load latch, start timer, count timer A */ 41 | #define ciaStopTimer 0x00 /* Stop timer */ 42 | 43 | #define ciaNone 0x1f /* Joy stick direction masks */ 44 | #define ciaFire 0x10 45 | #define ciaUp 0x01 46 | #define ciaDown 0x02 47 | #define ciaLeft 0x04 48 | #define ciaRight 0x08 49 | #define ciaUpLeft 0x05 50 | #define ciaUpRight 0x09 51 | #define ciaDownLeft 0x06 52 | #define ciaDownRight 0x0a 53 | 54 | #define ciaPotsPort1 0x40 /* 4066 analog switch settings for CIA 1 */ 55 | #define ciaPotsPort2 0x80 56 | 57 | #define ciaMs 1022 /* ~1 millisecond using CIA microsecond timer */ 58 | 59 | extern unsigned char __LIB__ getKeyCol(const unsigned char keyVal); 60 | extern unsigned char __LIB__ getLsKeyCol(const unsigned char keyVal); 61 | extern unsigned char __LIB__ getRsKeyCol(const unsigned char keyVal); 62 | extern unsigned char __LIB__ getKey(const unsigned char keyRow); 63 | extern void __LIB__ getKeys(const unsigned char* ciaKeyScan); 64 | extern unsigned char __LIB__ decodeKey(); 65 | extern void __LIB__ initCia(); 66 | extern void __LIB__ doneCia(); 67 | extern void __LIB__ startTimerAB(const unsigned int cia, const unsigned int timerA, const unsigned int timerB, const unsigned char latch); 68 | extern void __LIB__ setCiaTod(const unsigned int cia, const unsigned char hour, const unsigned char min, const unsigned char sec, const unsigned char tenth); 69 | extern void __LIB__ startTimerA(const unsigned int cia, const unsigned int hz, const unsigned char latch); 70 | extern void __LIB__ startTimerB(const unsigned int cia, const unsigned int hz, const unsigned char latch); 71 | extern unsigned char __LIB__ getJoystick1(); 72 | extern unsigned char __LIB__ getJoystick2(); 73 | extern unsigned long __LIB__ todToMs(const unsigned int cia); 74 | extern unsigned char __LIB__ bcdToByte(const unsigned char bcd); 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /src/vic/vic_split_scr.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Copyright (c) Steven P. Goldsmith. All rights reserved. 3 | ; 4 | ; Assembled with Z88DK-Z80ASM. 5 | ; 6 | ; C callable function used to set variables used by IRQ service. 7 | ; Bitmap can be on top or bottom. 8 | ; 9 | 10 | SECTION code_clib 11 | PUBLIC vicSplitScr 12 | PUBLIC _vicSplitScr 13 | PUBLIC _irq1 14 | 15 | ; IRQ vector 16 | 17 | vector equ 0fdfeh 18 | 19 | ; Return address 20 | 21 | return: 22 | 23 | defw 0 24 | 25 | ; Raster start line for mode 1 26 | 27 | raster1: 28 | 29 | defw 0 30 | 31 | ; Control register in low byte and memory register in high byte for mode 1 32 | 33 | ctrlReg1: 34 | 35 | defw 0 36 | 37 | ; Raster start line for mode 2 38 | 39 | raster2: 40 | 41 | defw 0 42 | 43 | ; Control register in low byte and memory register in high byte for mode 2 44 | 45 | ctrlReg2: 46 | 47 | defw 0 48 | 49 | ; This code can be called from C to store values used in the IRQ service routine 50 | 51 | vicSplitScr: 52 | _vicSplitScr: 53 | pop hl ; Return address 54 | ld (return),hl ; Save return address 55 | pop hl ; Bitmap address 56 | ld (ctrlReg2),hl ; Save ctrlReg2 value 57 | pop hl ; raster2 value 58 | ld (raster2),hl ; Save raster2 value 59 | pop de ; ctrlReg1 value 60 | ld (ctrlReg1),de ; Save ctrlReg1 value 61 | pop bc ; raster1 value 62 | ld (raster1),bc ; Save raster1 value 63 | push bc 64 | push de 65 | ld hl,(raster2) ; Get saved raster2 66 | push hl 67 | ld hl,(ctrlReg2) ; Get saved ctrlReg2 68 | push hl 69 | ld hl,(return) ; Get saved return address 70 | push hl 71 | ret 72 | 73 | ; This is the IRQ service routine which is looked up in the C code 74 | 75 | _irq1: 76 | push af 77 | push bc 78 | push hl 79 | ld bc,0d012h ; VIC raster line 80 | ld a,(raster2) ; Next raster line 81 | out (c),a ; Set line to fire IRQ on 82 | dec c ; bc = 0d011h VIC control register 1 83 | ld hl,(ctrlReg1) 84 | out (c),l ; Set VIC control register 1 85 | ld bc,0d018h ; VIC memory control register 86 | out (c),h ; Set VIC memory control register 87 | ld bc,irq2 88 | ld (vector),bc ; Change IRQ vector to irq2 89 | ld bc,0d019h 90 | ld a,0ffh 91 | out (c),a ; Ack raster interrupt 92 | pop hl 93 | pop bc 94 | pop af 95 | ei 96 | ret 97 | irq2: 98 | push af 99 | push bc 100 | push de 101 | ld bc,0d011h ; VIC control register 1 102 | ld de,(ctrlReg2) 103 | nop ; Add time to move raster into border 104 | nop 105 | nop 106 | nop 107 | out (c),e ; Set VIC memory control register 108 | ld bc,0d018h ; VIC memory control register 109 | out (c),d ; Set VIC memory control register 110 | ld bc,0d012h ; VIC raster line 111 | ld a,(raster1) ; Next raster line 112 | out (c),a ; Set line to fire IRQ on 113 | ld bc,_irq1 114 | ld (vector),bc ; Change IRQ vector to _irq1 115 | ld bc,0d019h 116 | ld a,0ffh 117 | out (c),a ; Ack raster interrupt 118 | pop de 119 | pop bc 120 | pop af 121 | ei 122 | ret 123 | --------------------------------------------------------------------------------