;-------------------------------------------------------- ; File Created by SDCC : free open source ISO C Compiler ; Version 4.6.0 #16555 (MINGW64) ;-------------------------------------------------------- .module main .optsdcc -mz80 sdcccall(1) ;-------------------------------------------------------- ; Public variables in this module ;-------------------------------------------------------- .globl _main .globl _main_start .globl _xm_update_info .globl _draw_progress_bar .globl _xm_draw_stats_labels .globl _put_time .globl _put_dec3 .globl _put_hex2 .globl _xm_set_status_attr .globl _xm_draw_static_labels .globl _copy_file_name .globl _error_playback .globl _error_oom .globl _stop_on_error .globl _error_esp .globl _wait_for_manual_exit .globl _leave_playing_and_exit .globl _unload_and_exit .globl _about .globl _wait_frames .globl _wait_esc_key .globl _play_xm .globl _esp_init .globl _esp_create_obj .globl _esp_wait_status .globl _esp_rd_end .globl _esp_send_dma .globl _esp_wr_end .globl _esp_wr_reg32 .globl _esp_wr_reg8 .globl _esp_rd_regs .globl _esp_rd_reg32 .globl _esp_rd_reg8 .globl _esp_cmd .globl _wc_exit .globl _wc_prm_pl .globl _wc_gadrw .globl _wc_prsrw_attr .globl _wc_prsrw .globl _wc_key_space .globl _wc_key_pgdn .globl _wc_key_pgup .globl _wc_key_esc .globl _wc_load512 .globl _wc_rresb .globl _wc_prwow .globl _strlen .globl _state_esp .globl _bar_attr_ofs .globl _last_track_status .globl _xm_handle .globl _total_samples .globl _file_name .globl _p_file_name .globl _last_esp_status .globl _call_type .globl _file_ext .globl _filesize .globl _ret_sp .globl _fs_buf .globl _win_about .globl _win_xm .globl _esp_wait_busy .globl _xm_set_status .globl _xm_set_status_code ;-------------------------------------------------------- ; special function registers ;-------------------------------------------------------- _SPI_DATA = 0x0057 _SPI_CTRL = 0x0077 _BORDER = 0x00fe _TS_VCONFIG = 0x00af _TS_STATUS = 0x00af _TS_VPAGE = 0x01af _TS_GXOFFSL = 0x02af _TS_GXOFFSH = 0x03af _TS_GYOFFSL = 0x04af _TS_GYOFFSH = 0x05af _TS_TSCONFIG = 0x06af _TS_PALSEL = 0x07af _TS_BORDER = 0x0faf _TS_PAGE0 = 0x10af _TS_PAGE1 = 0x11af _TS_PAGE2 = 0x12af _TS_PAGE3 = 0x13af _TS_FMADDR = 0x15af _TS_TMPAGE = 0x16af _TS_T0GPAGE = 0x17af _TS_T1GPAGE = 0x18af _TS_SGPAGE = 0x19af _TS_DMASADDRL = 0x1aaf _TS_DMASADDRH = 0x1baf _TS_DMASADDRX = 0x1caf _TS_DMADADDRL = 0x1daf _TS_DMADADDRH = 0x1eaf _TS_DMADADDRX = 0x1faf _TS_SYSCONFIG = 0x20af _TS_MEMCONFIG = 0x21af _TS_HSINT = 0x22af _TS_VSINTL = 0x23af _TS_VSINTH = 0x24af _TS_DMAWPD = 0x25af _TS_DMALEN = 0x26af _TS_DMACTR = 0x27af _TS_DMASTATUS = 0x27af _TS_DMANUM = 0x28af _TS_FDDVIRT = 0x29af _TS_INTMASK = 0x2aaf _TS_CACHECONF = 0x2baf _TS_DMANUMH = 0x2caf _TS_DMAWPA = 0x2daf _TS_T0XOFFSL = 0x40af _TS_T0XOFFSH = 0x41af _TS_T0YOFFSL = 0x42af _TS_T0YOFFSH = 0x43af _TS_T1XOFFSL = 0x44af _TS_T1XOFFSH = 0x45af _TS_T1YOFFSL = 0x46af _TS_T1YOFFSH = 0x47af ;-------------------------------------------------------- ; ram data ;-------------------------------------------------------- .area _DATA _fs_buf:: .ds 4096 _ret_sp:: .ds 2 _filesize:: .ds 4 _file_ext:: .ds 1 _call_type:: .ds 1 _last_esp_status:: .ds 1 _p_file_name:: .ds 2 _file_name:: .ds 33 _total_samples:: .ds 4 _xm_handle:: .ds 1 _last_track_status:: .ds 1 _status_buf: .ds 24 _status_code_buf: .ds 24 _hexbuf: .ds 2 _decbuf: .ds 3 _timebuf: .ds 5 _barbuf: .ds 32 _bar_attr_ofs:: .ds 2 ;-------------------------------------------------------- ; ram data ;-------------------------------------------------------- .area _INITIALIZED _state_esp:: .ds 1 ;-------------------------------------------------------- ; absolute ram data ;-------------------------------------------------------- .area _DABS (ABS) .area _DABS (ABS) ;-------------------------------------------------------- ; global & static initialisations ;-------------------------------------------------------- .area _HOME .area _GSINIT .area _GSFINAL .area _GSINIT ;-------------------------------------------------------- ; Home ;-------------------------------------------------------- .area _HOME .area _HOME ;-------------------------------------------------------- ; code ;-------------------------------------------------------- .area _CODE ;src/wc_api.c:47: void wc_exit(u8 rc) __naked ; --------------------------------- ; Function wc_exit ; --------------------------------- _wc_exit:: ;src/wc_api.c:53: __endasm; ld sp, (_ret_sp) ret ;src/wc_api.c:54: } ;src/esp32.c:18: void esp_cmd(u8 cmd) ; --------------------------------- ; Function esp_cmd ; --------------------------------- _esp_cmd:: ld c, a ;src/esp32.c:20: SPI_CTRL = SPI_ESP_CS_ON; ld a, #0x13 out (_SPI_CTRL), a ;src/esp32.c:21: SPI_DATA = ESP_SPI_CMD_WR_REGS; ld a, #0x01 out (_SPI_DATA), a ;src/esp32.c:22: SPI_DATA = ESP_REG_COMMAND; xor a, a out (_SPI_DATA), a ;src/esp32.c:23: SPI_DATA; // dummy in a, (_SPI_DATA) ;src/esp32.c:24: SPI_DATA = cmd; // Command ld a, c out (_SPI_DATA), a ;src/esp32.c:25: SPI_DATA = ESP_ST_IDLE; // Reset status xor a, a out (_SPI_DATA), a ;src/esp32.c:26: SPI_CTRL = SPI_ESP_CS_OFF; ld a, #0x03 out (_SPI_CTRL), a ;src/esp32.c:27: } ret ;src/esp32.c:29: u8 esp_rd_reg8(u8 reg) ; --------------------------------- ; Function esp_rd_reg8 ; --------------------------------- _esp_rd_reg8:: ld c, a ;src/esp32.c:31: SPI_CTRL = SPI_ESP_CS_ON; ld a, #0x13 out (_SPI_CTRL), a ;src/esp32.c:32: SPI_DATA = ESP_SPI_CMD_RD_REGS; ld a, #0x02 out (_SPI_DATA), a ;src/esp32.c:33: SPI_DATA = reg; ld a, c out (_SPI_DATA), a ;src/esp32.c:34: SPI_DATA; // dummy in a, (_SPI_DATA) ;src/esp32.c:35: SPI_DATA; // dummy in a, (_SPI_DATA) ;src/esp32.c:36: u8 rc = SPI_DATA; in a, (_SPI_DATA) ld c, a ;src/esp32.c:37: SPI_CTRL = SPI_ESP_CS_OFF; ld a, #0x03 out (_SPI_CTRL), a ;src/esp32.c:39: return rc; ld a, c ;src/esp32.c:40: } ret ;src/esp32.c:42: u32 esp_rd_reg32(u8 reg) ; --------------------------------- ; Function esp_rd_reg32 ; --------------------------------- _esp_rd_reg32:: push ix ld ix, #0 add ix, sp push af push af ld c, a ;src/esp32.c:44: SPI_CTRL = SPI_ESP_CS_ON; ld a, #0x13 out (_SPI_CTRL), a ;src/esp32.c:45: SPI_DATA = ESP_SPI_CMD_RD_REGS; ld a, #0x02 out (_SPI_DATA), a ;src/esp32.c:46: SPI_DATA = reg; ld a, c out (_SPI_DATA), a ;src/esp32.c:47: SPI_DATA; // dummy in a, (_SPI_DATA) ;src/esp32.c:48: SPI_DATA; // dummy in a, (_SPI_DATA) ;src/esp32.c:49: u32 rc = SPI_DATA; in a, (_SPI_DATA) ld c, a ;src/esp32.c:50: rc |= (u32)SPI_DATA << 8; in a, (_SPI_DATA) ld d, a ld e, c ;src/esp32.c:51: rc |= (u32)SPI_DATA << 16; in a, (_SPI_DATA) ld -4 (ix), a xor a, a ld -3 (ix), a ld -2 (ix), a ld -1 (ix), a ld a, -4 (ix) ld -2 (ix), a xor a, a ld -1 (ix), a ld -4 (ix), a ld -3 (ix), a ld l, -2 (ix) ;src/esp32.c:52: rc |= (u32)SPI_DATA << 24; in a, (_SPI_DATA) ld -4 (ix), a xor a, a ld -3 (ix), a ld -2 (ix), a ld -1 (ix), a ld a, -4 (ix) ld -1 (ix), a xor a, a ld -4 (ix), a ld -3 (ix), a ld -2 (ix), a ld h, -1 (ix) ;src/esp32.c:53: SPI_CTRL = SPI_ESP_CS_OFF; ld a, #0x03 out (_SPI_CTRL), a ;src/esp32.c:55: return rc; ;src/esp32.c:56: } ld sp, ix pop ix ret ;src/esp32.c:58: void esp_rd_regs(u8 reg, void *data, u8 size) ; --------------------------------- ; Function esp_rd_regs ; --------------------------------- _esp_rd_regs:: ld c, a ;src/esp32.c:60: u8 *d = (u8*)data; ;src/esp32.c:62: SPI_CTRL = SPI_ESP_CS_ON; ld a, #0x13 out (_SPI_CTRL), a ;src/esp32.c:63: SPI_DATA = ESP_SPI_CMD_RD_REGS; ld a, #0x02 out (_SPI_DATA), a ;src/esp32.c:64: SPI_DATA = reg; ld a, c out (_SPI_DATA), a ;src/esp32.c:65: SPI_DATA; // dummy in a, (_SPI_DATA) ;src/esp32.c:66: SPI_DATA; // dummy in a, (_SPI_DATA) ;src/esp32.c:67: while (size--) *d++ = SPI_DATA; ld iy, #2 add iy, sp ld c, 0 (iy) 00101$: ld a, c dec c or a, a jr z, 00103$ in a, (_SPI_DATA) ld (de), a inc de jp 00101$ 00103$: ;src/esp32.c:68: SPI_CTRL = SPI_ESP_CS_OFF; ld a, #0x03 out (_SPI_CTRL), a ;src/esp32.c:69: } pop hl inc sp jp (hl) ;src/esp32.c:71: void esp_wr_reg8(u8 reg, u8 data) ; --------------------------------- ; Function esp_wr_reg8 ; --------------------------------- _esp_wr_reg8:: ld b, a ld c, l ;src/esp32.c:73: SPI_CTRL = SPI_ESP_CS_ON; ld a, #0x13 out (_SPI_CTRL), a ;src/esp32.c:74: SPI_DATA = ESP_SPI_CMD_WR_REGS; ld a, #0x01 out (_SPI_DATA), a ;src/esp32.c:75: SPI_DATA = reg; ld a, b out (_SPI_DATA), a ;src/esp32.c:76: SPI_DATA; // dummy in a, (_SPI_DATA) ;src/esp32.c:77: SPI_DATA = data; ld a, c out (_SPI_DATA), a ;src/esp32.c:78: SPI_CTRL = SPI_ESP_CS_OFF; ld a, #0x03 out (_SPI_CTRL), a ;src/esp32.c:79: } ret ;src/esp32.c:81: void esp_wr_reg32(u8 reg, u32 data) ; --------------------------------- ; Function esp_wr_reg32 ; --------------------------------- _esp_wr_reg32:: ld c, a ;src/esp32.c:83: SPI_CTRL = SPI_ESP_CS_ON; ld a, #0x13 out (_SPI_CTRL), a ;src/esp32.c:84: SPI_DATA = ESP_SPI_CMD_WR_REGS; ld a, #0x01 out (_SPI_DATA), a ;src/esp32.c:85: SPI_DATA = reg; ld a, c out (_SPI_DATA), a ;src/esp32.c:86: SPI_DATA; // dummy in a, (_SPI_DATA) ;src/esp32.c:87: SPI_DATA = (u8)data; ld iy, #2 add iy, sp ld a, 0 (iy) out (_SPI_DATA), a ;src/esp32.c:88: SPI_DATA = (u8)(data >> 8); ld a, 1 (iy) out (_SPI_DATA), a ;src/esp32.c:89: SPI_DATA = (u8)(data >> 16); ld a, 2 (iy) out (_SPI_DATA), a ;src/esp32.c:90: SPI_DATA = (u8)(data >> 24); ld a, 3 (iy) out (_SPI_DATA), a ;src/esp32.c:91: SPI_CTRL = SPI_ESP_CS_OFF; ld a, #0x03 out (_SPI_CTRL), a ;src/esp32.c:92: } pop hl pop af pop af jp (hl) ;src/esp32.c:94: void esp_wr_end() ; --------------------------------- ; Function esp_wr_end ; --------------------------------- _esp_wr_end:: ;src/esp32.c:96: SPI_CTRL = SPI_ESP_CS_ON; ld a, #0x13 out (_SPI_CTRL), a ;src/esp32.c:97: SPI_DATA = ESP_SPI_CMD_W_END; ld a, #0x07 out (_SPI_DATA), a ;src/esp32.c:98: SPI_DATA; // dummy in a, (_SPI_DATA) ;src/esp32.c:99: SPI_CTRL = SPI_ESP_CS_OFF; ld a, #0x03 out (_SPI_CTRL), a ;src/esp32.c:100: } ret ;src/esp32.c:102: void esp_send_dma(u16 a, u8 p, u16 l, u16 n) ; --------------------------------- ; Function esp_send_dma ; --------------------------------- _esp_send_dma:: ld a, l ;src/esp32.c:105: TS_DMASADDRL = (u8)a; ld bc, #_TS_DMASADDRL out (c), a ;src/esp32.c:106: TS_DMASADDRH = (u8)((u16)a >> 8); ld a, h ld bc, #_TS_DMASADDRH out (c), a ;src/esp32.c:107: TS_DMASADDRX = p; ld iy, #2 add iy, sp ld a, 0 (iy) ld bc, #_TS_DMASADDRX out (c), a ;src/esp32.c:108: TS_DMALEN = (u8)((l >> 1) - 1); ld a, 1 (iy) ld c, 2 (iy) inc iy srl c rr a dec a ld bc, #_TS_DMALEN out (c), a ;src/esp32.c:109: TS_DMANUM = (u8)(n - 1); ld a, 2 (iy) dec a ld bc, #_TS_DMANUM out (c), a ;src/esp32.c:111: SPI_CTRL = SPI_ESP_CS_ON; ld a, #0x13 out (_SPI_CTRL), a ;src/esp32.c:112: SPI_DATA = ESP_SPI_CMD_WR_DATA; ld a, #0x03 out (_SPI_DATA), a ;src/esp32.c:113: SPI_DATA; // dummy in a, (_SPI_DATA) ;src/esp32.c:114: SPI_DATA; // dummy in a, (_SPI_DATA) ;src/esp32.c:115: TS_DMACTR = TS_DMA_RAM_SPI; ld a, #0x82 ld bc, #_TS_DMACTR out (c), a ;src/esp32.c:116: while (TS_DMASTATUS & 0x80); 00101$: ld a, #>(_TS_DMASTATUS) in a, (#<(_TS_DMASTATUS)) rlca jr c, 00101$ ;src/esp32.c:117: SPI_CTRL = SPI_ESP_CS_OFF; ld a, #0x03 out (_SPI_CTRL), a ;src/esp32.c:119: esp_wr_end(); call _esp_wr_end ;src/esp32.c:120: esp_wait_busy(100); // 2s - esp32 consuming one DMA'd chunk should be near-instant ld hl, #0x0064 call _esp_wait_busy ;src/esp32.c:121: } pop hl pop af pop af inc sp jp (hl) ;src/esp32.c:123: void esp_rd_end() ; --------------------------------- ; Function esp_rd_end ; --------------------------------- _esp_rd_end:: ;src/esp32.c:125: SPI_CTRL = SPI_ESP_CS_ON; ld a, #0x13 out (_SPI_CTRL), a ;src/esp32.c:126: SPI_DATA = ESP_SPI_CMD_R_END; ld a, #0x08 out (_SPI_DATA), a ;src/esp32.c:127: SPI_DATA; // dummy in a, (_SPI_DATA) ;src/esp32.c:128: SPI_CTRL = SPI_ESP_CS_OFF; ld a, #0x03 out (_SPI_CTRL), a ;src/esp32.c:129: } ret ;src/esp32.c:139: u8 esp_wait_status(u8 status, u16 max_frames) ; --------------------------------- ; Function esp_wait_status ; --------------------------------- _esp_wait_status:: push ix ld ix, #0 add ix, sp ld hl, #-5 add hl, sp ld sp, hl ld -1 (ix), a ld -3 (ix), e ld -2 (ix), d ;src/esp32.c:141: u16 start = *(u16*)_TMN; ld hl, #0x6009 ld a, (hl) ld -5 (ix), a inc hl ld a, (hl) ld -4 (ix), a ;src/esp32.c:143: while ((u16)(*(u16*)_TMN - start) < max_frames) 00103$: ld hl, (#0x6009) ld a, l sub a, -5 (ix) ld c, a ld a, h sbc a, -4 (ix) ld b, a ld a, c sub a, -3 (ix) ld a, b sbc a, -2 (ix) jr nc, 00105$ ;src/esp32.c:145: if (esp_rd_reg8(ESP_REG_STATUS) == status) ld a, #0x01 call _esp_rd_reg8 sub a, -1 (ix) jr nz, 00103$ ;src/esp32.c:146: return 1; ld a, #0x01 jp 00106$ 00105$: ;src/esp32.c:149: return 0; xor a, a 00106$: ;src/esp32.c:150: } ld sp, ix pop ix ret ;src/esp32.c:152: u8 esp_wait_busy(u16 max_frames) ; --------------------------------- ; Function esp_wait_busy ; --------------------------------- _esp_wait_busy:: push ix ld ix, #0 add ix, sp push af push af ld -2 (ix), l ld -1 (ix), h ;src/esp32.c:154: u16 start = *(u16*)_TMN; ld hl, #0x6009 ld a, (hl) ld -4 (ix), a inc hl ld a, (hl) ld -3 (ix), a ;src/esp32.c:156: while ((u16)(*(u16*)_TMN - start) < max_frames) 00103$: ld hl, (#0x6009) ld a, l sub a, -4 (ix) ld c, a ld a, h sbc a, -3 (ix) ld b, a ld a, c sub a, -2 (ix) ld a, b sbc a, -1 (ix) jr nc, 00105$ ;src/esp32.c:158: if (esp_rd_reg8(ESP_REG_STATUS) != ESP_ST_BUSY) ld a, #0x01 call _esp_rd_reg8 cp a, #0x02 jr z, 00103$ ;src/esp32.c:159: return 1; ld a, #0x01 jp 00106$ 00105$: ;src/esp32.c:162: return 0; xor a, a 00106$: ;src/esp32.c:163: } ld sp, ix pop ix ret ;src/esp32.c:165: int esp_create_obj(u32 size, u8 type) ; --------------------------------- ; Function esp_create_obj ; --------------------------------- _esp_create_obj:: ;src/esp32.c:167: esp_wr_reg32(ESP_REG_DATA_SIZE, size); push hl push de ld a, #0x03 call _esp_wr_reg32 ;src/esp32.c:168: esp_wr_reg8(ESP_REG_OBJ_TYPE, type); ld iy, #2 add iy, sp ld l, 0 (iy) ld a, #0x02 call _esp_wr_reg8 ;src/esp32.c:169: esp_cmd(ESP_CMD_MAKE_OBJECT); ld a, #0xe0 call _esp_cmd ;src/esp32.c:170: esp_wait_busy(100); // 2s - object allocation should be near-instant ld hl, #0x0064 call _esp_wait_busy ;src/esp32.c:173: return esp_rd_reg8(ESP_REG_OBJ_HANDLE); ld a, #0x0b call _esp_rd_reg8 ld e, a ld d, #0x00 ;src/esp32.c:174: } pop hl inc sp jp (hl) ;src/main.c:101: bool esp_init() ; --------------------------------- ; Function esp_init ; --------------------------------- _esp_init:: ;src/main.c:103: esp_cmd(ESP_CMD_NOP); xor a, a call _esp_cmd ;src/main.c:104: esp_rd_end(); call _esp_rd_end ;src/main.c:105: esp_wr_end(); call _esp_wr_end ;src/main.c:109: return true; ld a, #0x01 ;src/main.c:110: } ret _win_xm: .db #0x81 ; 129 .db #0x00 ; 0 .db #0x19 ; 25 .db #0x0a ; 10 .db #0x28 ; 40 .db #0x0c ; 12 .db #0x70 ; 112 'p' .db #0x00 ; 0 .dw #0x0000 .db #0x00 ; 0 .db #0x00 ; 0 .dw __str_0 .dw __str_1 .dw __str_1 _win_about: .db #0x01 ; 1 .db #0x00 ; 0 .db #0x16 ; 22 .db #0x0a ; 10 .db #0x24 ; 36 .db #0x05 ; 5 .db #0x4f ; 79 'O' .db #0x00 ; 0 .dw #0x0000 .db #0x00 ; 0 .db #0x00 ; 0 .dw __str_2 .dw __str_1 .dw __str_3 __str_0: .db 0x0e .ascii " XM/XMZ/S3M Player v0.1 " .db 0x00 __str_1: .db 0x00 __str_2: .db 0x0e .ascii " About " .db 0x00 __str_3: .db 0x0e .db 0x0c .db 0x01 .ascii "XM Player v0.1" .db 0x00 ;src/main.c:114: bool play_xm() ; --------------------------------- ; Function play_xm ; --------------------------------- _play_xm:: push ix ld ix, #0 add ix, sp ld hl, #-20 add hl, sp ld sp, hl ;src/main.c:116: esp_cmd(ESP_CMD_TRACK_STOP); ld a, #0xa2 call _esp_cmd ;src/main.c:117: esp_wait_busy(100); // 2s - both should be near-instant ld hl, #0x0064 call _esp_wait_busy ;src/main.c:118: esp_cmd(ESP_CMD_KILL_OBJECTS); ld a, #0xe4 call _esp_cmd ;src/main.c:119: esp_wait_busy(100); ld hl, #0x0064 call _esp_wait_busy ;src/main.c:122: switch (file_ext) ld a, (_file_ext) dec a jr z, 00101$ ld a, (_file_ext) sub a, #0x02 jr z, 00102$ jp 00103$ ;src/main.c:124: case EXT_XMZ: obj_type = OBJ_TYPE_ZIP; break; 00101$: ld a, #0x08 jp 00104$ ;src/main.c:125: case EXT_S3M: obj_type = OBJ_TYPE_S3M; break; 00102$: ld a, #0x0c jp 00104$ ;src/main.c:126: default: obj_type = OBJ_TYPE_XM; break; 00103$: ld a, #0x05 ;src/main.c:127: } 00104$: ;src/main.c:129: xm_handle = esp_create_obj(filesize, obj_type); push af inc sp ld de, (_filesize) ld hl, (_filesize + 2) call _esp_create_obj ld hl, #_xm_handle ld (hl), e ;src/main.c:130: last_esp_status = esp_rd_reg8(ESP_REG_STATUS); ld a, #0x01 call _esp_rd_reg8 ld (#_last_esp_status), a ;src/main.c:131: if (last_esp_status != ESP_ST_READY) ld a, (_last_esp_status) dec a jr z, 00106$ ;src/main.c:132: return false; xor a, a jp 00118$ 00106$: ;src/main.c:134: u32 sz = filesize; ld hl, #12 add hl, sp ex de, hl ld hl, #_filesize ld bc, #4 ldir ;src/main.c:135: u32 offs = 0; xor a, a ld -4 (ix), a ld -3 (ix), a ld -2 (ix), a ld -1 (ix), a ;src/main.c:137: while (sz) 00107$: ld a, -5 (ix) or a, -6 (ix) or a, -7 (ix) or a, -8 (ix) jp z, 00109$ ;src/main.c:139: u32 s = min(sz, FS_BUF_SIZE); ld a, -7 (ix) sub a, #0x10 ld a, -6 (ix) sbc a, #0x00 ld a, -5 (ix) sbc a, #0x00 jr nc, 00120$ ld hl, #0 add hl, sp ex de, hl ld hl, #12 add hl, sp ld bc, #4 ldir jp 00121$ 00120$: ld -20 (ix), #0x00 ld -19 (ix), #0x10 xor a, a ld -18 (ix), a ld -17 (ix), a 00121$: ld hl, #5 add hl, sp ex de, hl ld hl, #0 add hl, sp ld bc, #4 ldir ;src/main.c:140: u8 sec = (s + 511) >> 9; ld a, -15 (ix) add a, #0xff ld a, -14 (ix) adc a, #0x01 ld b, a ld a, #0x00 adc a, #0x00 ld e, a ld a, #0x00 adc a, #0x00 ld d, a ld c, b ld b, e ld e, d srl e rr b rr c ;src/main.c:142: wc_load512((u16)fs_buf, sec); ld -9 (ix), c ld a, c push af inc sp ld hl, #_fs_buf call _wc_load512 ;src/main.c:144: esp_wr_reg32(ESP_REG_DATA_SIZE, s); ld hl, #0x0 push hl ld l, -15 (ix) ld h, -14 (ix) push hl ld a, #0x03 call _esp_wr_reg32 ;src/main.c:145: esp_wr_reg32(ESP_REG_DATA_OFFSET, offs); ld l, -2 (ix) ld h, -1 (ix) push hl ld l, -4 (ix) ld h, -3 (ix) push hl ld a, #0x07 call _esp_wr_reg32 ;src/main.c:146: esp_cmd(ESP_CMD_WRITE_OBJECT); ld a, #0xe1 call _esp_cmd ;src/main.c:147: esp_wait_status(ESP_ST_DATA_M2S, 100); // 2s - near-instant state transition ld de, #0x0064 ld a, #0x03 call _esp_wait_status ;src/main.c:148: esp_send_dma((u16)fs_buf, *(u8*)_PAGE2, 512, sec); ld a, -9 (ix) ld -11 (ix), a ld -10 (ix), #0x00 ld a, (#0x6002) ld -9 (ix), a ld l, -11 (ix) ld h, #0x00 push hl ld hl, #0x0200 push hl ld a, -9 (ix) push af inc sp ld hl, #_fs_buf call _esp_send_dma ;src/main.c:150: offs += s; ld e, -15 (ix) ld d, -14 (ix) ld l, -4 (ix) ld h, -3 (ix) add hl, de ld -4 (ix), l ld -3 (ix), h ld a, -2 (ix) adc a, -13 (ix) ld -2 (ix), a jr nc, 00207$ inc -1 (ix) 00207$: ;src/main.c:151: sz -= s; ld a, -8 (ix) sub a, -15 (ix) ld -8 (ix), a ld a, -7 (ix) sbc a, -14 (ix) ld -7 (ix), a ld a, -6 (ix) sbc a, -13 (ix) ld -6 (ix), a ld a, -5 (ix) sbc a, -12 (ix) ld -5 (ix), a jp 00107$ 00109$: ;src/main.c:154: if (file_ext == EXT_XMZ) ld a, (_file_ext) dec a jr nz, 00113$ ;src/main.c:159: esp_wr_reg8(ESP_REG_OBJ_HANDLE, xm_handle); ld a, (_xm_handle) ld l, a ld a, #0x0b call _esp_wr_reg8 ;src/main.c:160: esp_wr_reg8(ESP_REG_OBJ_TYPE, OBJ_TYPE_XM); ld l, #0x05 ld a, #0x02 call _esp_wr_reg8 ;src/main.c:161: esp_wr_reg32(ESP_REG_DATA_SIZE, filesize); ld hl, (_filesize + 2) push hl ld hl, (_filesize) push hl ld a, #0x03 call _esp_wr_reg32 ;src/main.c:162: esp_cmd(ESP_CMD_UNZIP); ld a, #0xf2 call _esp_cmd ;src/main.c:163: esp_wait_busy(250); // 5s - decompression time scales with file size ld hl, #0x00fa call _esp_wait_busy ;src/main.c:165: last_esp_status = esp_rd_reg8(ESP_REG_STATUS); ld a, #0x01 call _esp_rd_reg8 ld (#_last_esp_status), a ;src/main.c:166: if (last_esp_status != ESP_ST_READY) ld a, (_last_esp_status) dec a jr z, 00113$ ;src/main.c:167: return false; xor a, a jp 00118$ 00113$: ;src/main.c:170: esp_cmd(ESP_CMD_TRACK_INIT); ld a, #0xa0 call _esp_cmd ;src/main.c:176: esp_wait_busy(400); ld hl, #0x0190 call _esp_wait_busy ;src/main.c:178: last_esp_status = esp_rd_reg8(ESP_REG_STATUS); ld a, #0x01 call _esp_rd_reg8 ld (#_last_esp_status), a ;src/main.c:179: if (last_esp_status != ESP_ST_READY) ld a, (_last_esp_status) dec a jr z, 00115$ ;src/main.c:180: return false; xor a, a jp 00118$ 00115$: ;src/main.c:185: esp_wr_reg8(ESP_REG_OBJ_HANDLE, xm_handle); ld a, (_xm_handle) ld l, a ld a, #0x0b call _esp_wr_reg8 ;src/main.c:186: esp_wr_reg8(ESP_REG_TRACK_MAX_LOOP_COUNT, 1); ld l, #0x01 ld a, #0x3a call _esp_wr_reg8 ;src/main.c:187: esp_cmd(ESP_CMD_TRACK_SET_PARAMS); ld a, #0xa6 call _esp_cmd ;src/main.c:188: esp_wait_busy(100); // 2s - both should be near-instant ld hl, #0x0064 call _esp_wait_busy ;src/main.c:190: esp_cmd(ESP_CMD_TRACK_PLAY); ld a, #0xa1 call _esp_cmd ;src/main.c:191: esp_wait_busy(100); ld hl, #0x0064 call _esp_wait_busy ;src/main.c:193: last_esp_status = esp_rd_reg8(ESP_REG_STATUS); ld a, #0x01 call _esp_rd_reg8 ld (#_last_esp_status), a ;src/main.c:194: if (last_esp_status != ESP_ST_READY) ld a, (_last_esp_status) dec a jr z, 00117$ ;src/main.c:195: return false; xor a, a jp 00118$ 00117$: ;src/main.c:197: return true; ld a, #0x01 00118$: ;src/main.c:198: } ld sp, ix pop ix ret ;src/main.c:201: void wait_esc_key() ; --------------------------------- ; Function wait_esc_key ; --------------------------------- _wait_esc_key:: ;src/main.c:203: while (1) 00104$: ;src/main.c:207: __endasm; halt ;src/main.c:209: if (wc_key_esc()) call _wc_key_esc or a, a jr z, 00104$ ;src/main.c:210: break; ;src/main.c:212: } ret ;src/main.c:214: void wait_frames(u8 n) ; --------------------------------- ; Function wait_frames ; --------------------------------- _wait_frames:: ld c, a ;src/main.c:216: while (n--) 00101$: ld a, c dec c or a, a ret z ;src/main.c:220: __endasm; halt ;src/main.c:222: } jp 00101$ ;src/main.c:224: void about() ; --------------------------------- ; Function about ; --------------------------------- _about:: ;src/main.c:226: wc_prwow(&win_about); ld hl, #_win_about call _wc_prwow ;src/main.c:227: wait_esc_key(); call _wait_esc_key ;src/main.c:228: wc_rresb(&win_about); ld hl, #_win_about call _wc_rresb ;src/main.c:229: wc_exit(WC_EXIT); xor a, a ;src/main.c:230: } jp _wc_exit ;src/main.c:235: void unload_and_exit(WC_EXIT_SIGNAL sig) ; --------------------------------- ; Function unload_and_exit ; --------------------------------- _unload_and_exit:: dec sp ld iy, #0 add iy, sp ld 0 (iy), a ;src/main.c:237: esp_cmd(ESP_CMD_TRACK_STOP); ld a, #0xa2 call _esp_cmd ;src/main.c:238: esp_wait_busy(100); // 2s - both should be near-instant ld hl, #0x0064 call _esp_wait_busy ;src/main.c:239: esp_cmd(ESP_CMD_KILL_OBJECTS); ld a, #0xe4 call _esp_cmd ;src/main.c:240: esp_wait_busy(100); ld hl, #0x0064 call _esp_wait_busy ;src/main.c:241: wc_rresb(&win_xm); ld hl, #_win_xm call _wc_rresb ;src/main.c:242: wc_exit(sig); ld hl, #0 add hl, sp ld a, (hl) inc sp jp _wc_exit ;src/main.c:243: } inc sp ret ;src/main.c:247: void leave_playing_and_exit() ; --------------------------------- ; Function leave_playing_and_exit ; --------------------------------- _leave_playing_and_exit:: ;src/main.c:249: wc_rresb(&win_xm); ld hl, #_win_xm call _wc_rresb ;src/main.c:250: wc_exit(WC_EXIT); xor a, a ;src/main.c:251: } jp _wc_exit ;src/main.c:257: void wait_for_manual_exit() ; --------------------------------- ; Function wait_for_manual_exit ; --------------------------------- _wait_for_manual_exit:: ;src/main.c:259: while (1) 00108$: ;src/main.c:263: __endasm; halt ;src/main.c:265: if (wc_key_pgdn()) call _wc_key_pgdn or a, a jr z, 00102$ ;src/main.c:266: unload_and_exit(WC_NEXT_FILE); ld a, #0x02 call _unload_and_exit 00102$: ;src/main.c:268: if (wc_key_pgup()) call _wc_key_pgup or a, a jr z, 00104$ ;src/main.c:269: unload_and_exit(WC_PREV_FILE); ld a, #0x04 call _unload_and_exit 00104$: ;src/main.c:271: if (wc_key_esc()) call _wc_key_esc or a, a jr z, 00108$ ;src/main.c:272: unload_and_exit(WC_EXIT); xor a, a call _unload_and_exit ;src/main.c:274: } jp 00108$ ;src/main.c:280: void error_esp() ; --------------------------------- ; Function error_esp ; --------------------------------- _error_esp:: ;src/main.c:285: xm_set_status_code("No ESP32 found", state_esp); ld a, (_state_esp) push af inc sp ld hl, #___str_4 call _xm_set_status_code ;src/main.c:286: wait_esc_key(); call _wait_esc_key ;src/main.c:287: wc_rresb(&win_xm); ld hl, #_win_xm call _wc_rresb ;src/main.c:288: wc_exit(WC_EXIT); xor a, a ;src/main.c:289: } jp _wc_exit ___str_4: .ascii "No ESP32 found" .db 0x00 ;src/main.c:299: u8 stop_on_error() ; --------------------------------- ; Function stop_on_error ; --------------------------------- _stop_on_error:: ;src/main.c:301: return wc_prm_pl(1) == 2; ld a, #0x01 call _wc_prm_pl cp a, #0x02 ld a, #0x01 ret z xor a, a ;src/main.c:302: } ret ;src/main.c:304: void error_oom() ; --------------------------------- ; Function error_oom ; --------------------------------- _error_oom:: ;src/main.c:306: xm_set_status_code("File too large", last_esp_status); ld a, (_last_esp_status) push af inc sp ld hl, #___str_5 call _xm_set_status_code ;src/main.c:308: if (stop_on_error()) call _stop_on_error or a, a jr z, 00102$ ;src/main.c:309: wait_for_manual_exit(); call _wait_for_manual_exit 00102$: ;src/main.c:311: wait_frames(50); // show the error for ~1 second (50Hz), then auto-advance ld a, #0x32 call _wait_frames ;src/main.c:312: wc_rresb(&win_xm); ld hl, #_win_xm call _wc_rresb ;src/main.c:313: wc_exit(WC_NEXT_FILE); ld a, #0x02 ;src/main.c:314: } jp _wc_exit ___str_5: .ascii "File too large" .db 0x00 ;src/main.c:316: void error_playback() ; --------------------------------- ; Function error_playback ; --------------------------------- _error_playback:: ;src/main.c:318: xm_set_status_code("Playback error", last_esp_status); ld a, (_last_esp_status) push af inc sp ld hl, #___str_6 call _xm_set_status_code ;src/main.c:320: if (stop_on_error()) call _stop_on_error or a, a jr z, 00102$ ;src/main.c:321: wait_for_manual_exit(); call _wait_for_manual_exit 00102$: ;src/main.c:323: wait_frames(50); // show the error for ~1 second (50Hz), then auto-advance ld a, #0x32 call _wait_frames ;src/main.c:324: wc_rresb(&win_xm); ld hl, #_win_xm call _wc_rresb ;src/main.c:325: wc_exit(WC_NEXT_FILE); ld a, #0x02 ;src/main.c:326: } jp _wc_exit ___str_6: .ascii "Playback error" .db 0x00 ;src/main.c:333: void copy_file_name() ; --------------------------------- ; Function copy_file_name ; --------------------------------- _copy_file_name:: ;src/main.c:335: u8 *src = (u8*)p_file_name; ld bc, (_p_file_name) ;src/main.c:338: while (src[i] && i < sizeof(file_name) - 1) ld e, #0x00 00102$: ld l, e ld h, #0x00 add hl, bc ld d, (hl) ;src/main.c:340: file_name[i] = src[i]; ld a, #<(_file_name) add a, e ld l, a ld a, #>(_file_name) adc a, #0x00 ld h, a ;src/main.c:338: while (src[i] && i < sizeof(file_name) - 1) ld a, d or a, a jr z, 00104$ ld a, e sub a, #0x20 jr nc, 00104$ ;src/main.c:340: file_name[i] = src[i]; ld (hl), d ;src/main.c:341: i++; inc e jp 00102$ 00104$: ;src/main.c:343: file_name[i] = 0; ld (hl), #0x00 ;src/main.c:344: } ret ;src/main.c:377: void xm_draw_static_labels() ; --------------------------------- ; Function xm_draw_static_labels ; --------------------------------- _xm_draw_static_labels:: ;src/main.c:379: wc_prsrw(&win_xm, "File:", ROW_FILE, 1, 5); ld hl, #0x0005 push hl ld hl, #0x102 push hl ld de, #___str_7 ld hl, #_win_xm call _wc_prsrw ;src/main.c:380: wc_prsrw_attr(&win_xm, file_name, ROW_FILE, 7, strlen(file_name), ATTR_VALUE); ld hl, #_file_name call _strlen ld a, #0x71 push af inc sp push de ld hl, #0x702 push hl ld de, #_file_name ld hl, #_win_xm call _wc_prsrw_attr ;src/main.c:381: wc_prsrw(&win_xm, "Status:", ROW_STATUS, 1, 7); ld hl, #0x0007 push hl ld hl, #0x103 push hl ld de, #___str_8 ld hl, #_win_xm call _wc_prsrw ;src/main.c:384: wc_prsrw(&win_xm, HINT_TEXT, ROW_HINT, 2, sizeof(HINT_TEXT) - 1); ld hl, #0x0024 push hl ld hl, #0x20a push hl ld de, #___str_9 ld hl, #_win_xm call _wc_prsrw ;src/main.c:385: } ret ___str_7: .ascii "File:" .db 0x00 ___str_8: .ascii "Status:" .db 0x00 ___str_9: .ascii "PgUp/PgDn:Track Esc:Stop Space:Leave" .db 0x00 ;src/main.c:391: void xm_set_status_attr(const char *msg, u8 attr) ; --------------------------------- ; Function xm_set_status_attr ; --------------------------------- _xm_set_status_attr:: push ix ld ix, #0 add ix, sp push af ;src/main.c:395: while (msg[i] && i < STATUS_VALUE_WIDTH) ld e, #0x00 00102$: ld a, e add a, l ld c, a ld a, #0x00 adc a, h ld b, a ld a, (bc) ld c, a or a, a jr z, 00119$ ld a, e sub a, #0x18 jr nc, 00119$ ;src/main.c:397: status_buf[i] = msg[i]; ld a, #<(_status_buf) add a, e ld -2 (ix), a ld a, #>(_status_buf) adc a, #0x00 ld -1 (ix), a push hl ld l, -2 (ix) ld h, -1 (ix) ld (hl), c pop hl ;src/main.c:398: i++; inc e jp 00102$ ;src/main.c:400: while (i < STATUS_VALUE_WIDTH) 00119$: 00105$: ld a, e sub a, #0x18 jr nc, 00107$ ;src/main.c:401: status_buf[i++] = ' '; ld hl, #_status_buf ld d, #0x00 add hl, de inc e ld (hl), #0x20 jp 00105$ 00107$: ;src/main.c:403: wc_prsrw_attr(&win_xm, status_buf, ROW_STATUS, STATUS_VALUE_X, STATUS_VALUE_WIDTH, attr); ld hl, #_win_xm ld a, 4 (ix) push af inc sp ld de, #0x0018 push de ld de, #0x903 push de ld de, #_status_buf call _wc_prsrw_attr ;src/main.c:404: } ld sp, ix pop ix pop hl inc sp jp (hl) ;src/main.c:406: void xm_set_status(const char *msg) ; --------------------------------- ; Function xm_set_status ; --------------------------------- _xm_set_status:: ;src/main.c:408: xm_set_status_attr(msg, ATTR_VALUE); ld a, #0x71 push af inc sp call _xm_set_status_attr ;src/main.c:409: } ret ;src/main.c:416: void xm_set_status_code(const char *msg, u8 code) ; --------------------------------- ; Function xm_set_status_code ; --------------------------------- _xm_set_status_code:: push ix ld ix, #0 add ix, sp dec sp ex de, hl ;src/main.c:421: while (msg[i] && i < sizeof(status_code_buf) - 7) ld c, #0x00 00102$: ld l, c ld h, #0x00 add hl, de ld b, (hl) ;src/main.c:423: status_code_buf[i] = msg[i]; ld a, #<(_status_code_buf) add a, c ld l, a ld a, #>(_status_code_buf) adc a, #0x00 ld h, a ;src/main.c:424: i++; ld a, c inc a ld -1 (ix), a ;src/main.c:421: while (msg[i] && i < sizeof(status_code_buf) - 7) ld a, b or a, a jr z, 00104$ ld a, c sub a, #0x11 jr nc, 00104$ ;src/main.c:423: status_code_buf[i] = msg[i]; ld (hl), b ;src/main.c:424: i++; ld c, -1 (ix) jp 00102$ 00104$: ;src/main.c:427: status_code_buf[i++] = ' '; ld c, -1 (ix) ld (hl), #0x20 ;src/main.c:428: status_code_buf[i++] = '('; ld l, c inc c ld h, #0x00 ld de, #_status_code_buf add hl, de ld (hl), #0x28 ;src/main.c:429: status_code_buf[i++] = '0'; ld l, c inc c ld h, #0x00 ld de, #_status_code_buf add hl, de ld (hl), #0x30 ;src/main.c:430: status_code_buf[i++] = 'x'; ld l, c inc c ld h, #0x00 ld de, #_status_code_buf add hl, de ld (hl), #0x78 ;src/main.c:431: status_code_buf[i++] = hexch[(code >> 4) & 0xF]; ld l, c inc c ld h, #0x00 ld de, #_status_code_buf add hl, de ld a, 4 (ix) rlca rlca rlca rlca and a, #0xf add a, #<(_xm_set_status_code_hexch_10000_129) ld e, a ld a, #0x00 adc a, #>(_xm_set_status_code_hexch_10000_129) ld d, a ld a, (de) ld (hl), a ;src/main.c:432: status_code_buf[i++] = hexch[code & 0xF]; ld l, c inc c ld h, #0x00 ld de, #_status_code_buf add hl, de ld a, 4 (ix) and a, #0x0f add a, #<(_xm_set_status_code_hexch_10000_129) ld e, a ld a, #0x00 adc a, #>(_xm_set_status_code_hexch_10000_129) ld d, a ld a, (de) ld (hl), a ;src/main.c:433: status_code_buf[i++] = ')'; ld l, c inc c ld h, #0x00 ld de, #_status_code_buf add hl, de ld (hl), #0x29 ;src/main.c:434: status_code_buf[i] = 0; ld l, c ld h, #0x00 ld de, #_status_code_buf add hl, de ld (hl), #0x00 ;src/main.c:436: xm_set_status_attr(status_code_buf, ATTR_ERROR); ld a, #0x72 push af inc sp ld hl, #_status_code_buf call _xm_set_status_attr ;src/main.c:437: } inc sp pop ix pop hl inc sp jp (hl) _xm_set_status_code_hexch_10000_129: .ascii "0123456789ABCDEF" .db 0x00 ;src/main.c:450: void put_hex2(char *dst, u8 val) ; --------------------------------- ; Function put_hex2 ; --------------------------------- _put_hex2:: push ix ld ix, #0 add ix, sp ex de, hl ;src/main.c:453: dst[0] = hexch[(val >> 4) & 0xF]; ld bc, #_put_hex2_hexch_10000_132+0 ld a, 4 (ix) rlca rlca rlca rlca and a, #0xf ld l, a ld h, #0x00 add hl, bc ld a, (hl) ld (de), a ;src/main.c:454: dst[1] = hexch[val & 0xF]; inc de ld a, 4 (ix) and a, #0x0f ld l, a ld h, #0x00 add hl, bc ld a, (hl) ld (de), a ;src/main.c:455: } pop ix pop hl inc sp jp (hl) _put_hex2_hexch_10000_132: .ascii "0123456789ABCDEF" .db 0x00 ;src/main.c:457: void put_dec3(char *dst, u16 val) ; --------------------------------- ; Function put_dec3 ; --------------------------------- _put_dec3:: push ix ld ix, #0 add ix, sp push af ld c, l ld b, h ;src/main.c:459: dst[0] = '0' + (val / 100) % 10; pop hl push de push bc ld de, #0x0064 ld l, -2 (ix) ld h, -1 (ix) call __divuint ex de, hl ld de, #0x000a call __moduint pop bc ld a, e add a, #0x30 ld (bc), a ;src/main.c:460: dst[1] = '0' + (val / 10) % 10; ld l, c ld h, b inc hl push hl push bc ld de, #0x000a ld l, -2 (ix) ld h, -1 (ix) call __divuint ex de, hl ld de, #0x000a call __moduint pop bc pop hl ld a, e add a, #0x30 ld (hl), a ;src/main.c:461: dst[2] = '0' + val % 10; inc bc inc bc push bc ld de, #0x000a ld l, -2 (ix) ld h, -1 (ix) call __moduint pop bc ld a, e add a, #0x30 ld (bc), a ;src/main.c:462: } ld sp, ix pop ix ret ;src/main.c:464: void put_time(char *dst, u32 sec) ; --------------------------------- ; Function put_time ; --------------------------------- _put_time:: push ix ld ix, #0 add ix, sp push hl ;src/main.c:466: u8 m = (sec / 60) % 100; ld hl, #0x0000 push hl ld l, #0x3c push hl ld e, 4 (ix) ld d, 5 (ix) ld l, 6 (ix) ld h, 7 (ix) call __divulong pop af pop af ld bc, #0x0000 push bc ld c, #0x64 push bc call __modulong pop af pop af ld c, e ;src/main.c:467: u8 s = sec % 60; push bc ld hl, #0x0000 push hl ld l, #0x3c push hl ld e, 4 (ix) ld d, 5 (ix) ld l, 6 (ix) ld h, 7 (ix) call __modulong pop af pop af pop bc ;src/main.c:469: dst[0] = '0' + (m / 10) % 10; ld d, c push de ld l, #0x0a ld a, d call __divuchar ld a, e ld l, #0x0a call __moduchar ld a, e pop de add a, #0x30 pop hl push hl ld (hl), a ;src/main.c:470: dst[1] = '0' + m % 10; pop bc push bc inc bc push bc push de ld l, #0x0a ld a, d call __moduchar ld a, e pop de pop bc add a, #0x30 ld (bc), a ;src/main.c:471: dst[2] = ':'; pop hl push hl inc hl inc hl ld (hl), #0x3a ;src/main.c:472: dst[3] = '0' + (s / 10) % 10; pop bc push bc inc bc inc bc inc bc push bc push de ld l, #0x0a ld a, e call __divuchar ld a, e ld l, #0x0a call __moduchar ld a, e pop de pop bc add a, #0x30 ld (bc), a ;src/main.c:473: dst[4] = '0' + s % 10; ld a, -2 (ix) add a, #0x04 ld c, a ld a, -1 (ix) adc a, #0x00 ld b, a push bc ld l, #0x0a ld a, e call __moduchar ld a, e pop bc add a, #0x30 ld (bc), a ;src/main.c:474: } ld sp, ix pop ix pop hl pop af pop af jp (hl) ;src/main.c:503: void xm_draw_stats_labels() ; --------------------------------- ; Function xm_draw_stats_labels ; --------------------------------- _xm_draw_stats_labels:: ;src/main.c:507: wc_prsrw(&win_xm, "Pattern:#", ROW_STATS, 1, 9); ld hl, #0x0009 push hl ld hl, #0x104 push hl ld de, #___str_12 ld hl, #_win_xm call _wc_prsrw ;src/main.c:508: wc_prsrw(&win_xm, " Row:#", ROW_STATS, 12, 7); ld hl, #0x0007 push hl ld hl, #0xc04 push hl ld de, #___str_13 ld hl, #_win_xm call _wc_prsrw ;src/main.c:509: wc_prsrw(&win_xm, " BPM:", ROW_STATS, 21, 6); ld hl, #0x0006 push hl ld hl, #0x1504 push hl ld de, #___str_14 ld hl, #_win_xm call _wc_prsrw ;src/main.c:511: wc_prsrw(&win_xm, "Time:", ROW_TIME, 1, 5); ld hl, #0x0005 push hl ld hl, #0x106 push hl ld de, #___str_15 ld hl, #_win_xm call _wc_prsrw ;src/main.c:512: wc_prsrw(&win_xm, " / ", ROW_TIME, 12, 3); ld hl, #0x0003 push hl ld hl, #0xc06 push hl ld de, #___str_16 ld hl, #_win_xm call _wc_prsrw ;src/main.c:514: for (i = 0; i < BAR_WIDTH; i++) ld de, #_barbuf+0 ld c, #0x00 00103$: ;src/main.c:515: barbuf[i] = ' '; ld l, c ld h, #0x00 add hl, de ld (hl), #0x20 ;src/main.c:514: for (i = 0; i < BAR_WIDTH; i++) inc c ld a, c sub a, #0x20 jr c, 00103$ ;src/main.c:516: wc_prsrw(&win_xm, barbuf, ROW_BAR, BAR_X, BAR_WIDTH); ;src/main.c:507: wc_prsrw(&win_xm, "Pattern:#", ROW_STATS, 1, 9); ;src/main.c:516: wc_prsrw(&win_xm, barbuf, ROW_BAR, BAR_X, BAR_WIDTH); ld hl, #0x0020 push hl ld hl, #0x408 push hl ld hl, #_win_xm call _wc_prsrw ;src/main.c:518: bar_attr_ofs = (wc_gadrw(&win_xm, ROW_BAR, BAR_X) & 0x3FFF) | 0x0080; ld hl, #0x408 push hl ld hl, #_win_xm call _wc_gadrw ld a, d and a, #0x3f ld d, a set 7, e ld (_bar_attr_ofs), de ;src/main.c:520: for (i = 0; i < BAR_WIDTH; i++) ld c, #0x00 00105$: ;src/main.c:521: *(volatile u8*)(0xC000 + bar_attr_ofs + i) = ATTR_BAR_EMPTY; ld hl, (_bar_attr_ofs) ld e, l ld a, h add a, #0xc0 ld d, a ld l, c ld h, #0x00 add hl, de ld (hl), #0x07 ;src/main.c:520: for (i = 0; i < BAR_WIDTH; i++) inc c ld a, c sub a, #0x20 jr c, 00105$ ;src/main.c:522: } ret ___str_12: .ascii "Pattern:#" .db 0x00 ___str_13: .ascii " Row:#" .db 0x00 ___str_14: .ascii " BPM:" .db 0x00 ___str_15: .ascii "Time:" .db 0x00 ___str_16: .ascii " / " .db 0x00 ;src/main.c:524: void draw_progress_bar(u32 samples, u32 total) ; --------------------------------- ; Function draw_progress_bar ; --------------------------------- _draw_progress_bar:: push ix ld ix, #0 add ix, sp ld c, e ld b, d ex de, hl ;src/main.c:528: if (total) ld a, 7 (ix) or a, 6 (ix) or a, 5 (ix) or a, 4 (ix) jr z, 00104$ ;src/main.c:530: filled = (u16)(((u32)samples * BAR_WIDTH) / total); ld l, c ld h, b ld a, #0x05 00146$: add hl, hl rl e rl d dec a jr nz, 00146$ ld c, 6 (ix) ld b, 7 (ix) push bc ld c, 4 (ix) ld b, 5 (ix) push bc ex de, hl call __divulong pop af pop af ;src/main.c:531: if (filled > BAR_WIDTH) ld c,e ld b,d ld a, #0x20 cp a, e ld a, #0x00 sbc a, d jr nc, 00120$ ;src/main.c:532: filled = BAR_WIDTH; ld bc, #0x0020 jp 00120$ 00104$: ;src/main.c:535: filled = 0; // total length unknown (measurement timed out) - show empty ld bc, #0x0000 ;src/main.c:537: for (i = 0; i < BAR_WIDTH; i++) 00120$: ld de, #0x0000 00107$: ;src/main.c:538: *(volatile u8*)(0xC000 + bar_attr_ofs + i) = (i < filled) ? ATTR_BAR_FILLED : ATTR_BAR_EMPTY; ld hl, (_bar_attr_ofs) ld a, h add a, #0xc0 ld h, a add hl, de ld a, e sub a, c ld a, d sbc a, b jr nc, 00111$ ld a, #0x40 jp 00112$ 00111$: ld a, #0x07 00112$: ld (hl), a ;src/main.c:537: for (i = 0; i < BAR_WIDTH; i++) inc de ld l, e ld h, d ld a, l sub a, #0x20 ld a, h sbc a, #0x00 jr c, 00107$ ;src/main.c:539: } pop ix pop hl pop af pop af jp (hl) ;src/main.c:541: void xm_update_info() ; --------------------------------- ; Function xm_update_info ; --------------------------------- _xm_update_info:: push ix ld ix, #0 add ix, sp ld hl, #-8 add hl, sp ld sp, hl ;src/main.c:547: esp_wr_reg8(ESP_REG_OBJ_HANDLE, xm_handle); ld a, (_xm_handle) ld l, a ld a, #0x0b call _esp_wr_reg8 ;src/main.c:548: esp_cmd(ESP_CMD_TRACK_GET_INFO); ld a, #0xa8 call _esp_cmd ;src/main.c:549: esp_wait_busy(50); // 1s - a plain info read should be near-instant ld hl, #0x0032 call _esp_wait_busy ;src/main.c:554: status = esp_rd_reg8(ESP_REG_TRACK_STATUS); ld a, #0x28 call _esp_rd_reg8 ld -1 (ix), a ;src/main.c:555: if (last_track_status == TRACK_OBJ_ST_PLAYING && status == TRACK_OBJ_ST_STOPPED) ld a, (_last_track_status) sub a, #0x21 jr nz, 00102$ ld a, -1 (ix) sub a, #0x20 jr nz, 00102$ ;src/main.c:557: esp_cmd(ESP_CMD_KILL_OBJECTS); ld a, #0xe4 call _esp_cmd ;src/main.c:558: esp_wait_busy(100); ld hl, #0x0064 call _esp_wait_busy ;src/main.c:559: wc_rresb(&win_xm); ld hl, #_win_xm call _wc_rresb ;src/main.c:560: wc_exit(WC_NEXT_FILE); ld a, #0x02 call _wc_exit 00102$: ;src/main.c:562: last_track_status = status; ld a, -1 (ix) ld (#_last_track_status), a ;src/main.c:564: pattern = esp_rd_reg8(ESP_REG_TRACK_PATTERN); ld a, #0x2b call _esp_rd_reg8 ld -6 (ix), a ;src/main.c:565: row = esp_rd_reg8(ESP_REG_TRACK_ROW); ld a, #0x2c call _esp_rd_reg8 ld -5 (ix), a ;src/main.c:566: esp_rd_regs(ESP_REG_TRACK_BPM, &bpm, 2); ld a, #0x02 push af inc sp ld hl, #1 add hl, sp ex de, hl ld a, #0x31 call _esp_rd_regs ;src/main.c:567: samples = esp_rd_reg32(ESP_REG_TRACK_SAMPLES); ld a, #0x2d call _esp_rd_reg32 ld -4 (ix), e ld -3 (ix), d ld -2 (ix), l ld -1 (ix), h ;src/main.c:569: if (!total_samples) ld a, (_total_samples+3) ld iy, #_total_samples or a, 2 (iy) or a, 1 (iy) or a, 0 (iy) jr nz, 00105$ ;src/main.c:570: total_samples = esp_rd_reg32(ESP_REG_TRACK_TOTAL_SAMPLES); ld a, #0x36 call _esp_rd_reg32 ld (_total_samples), de ld (_total_samples + 2), hl 00105$: ;src/main.c:572: put_hex2(hexbuf, pattern); ld a, -6 (ix) push af inc sp ld hl, #_hexbuf call _put_hex2 ;src/main.c:573: wc_prsrw_attr(&win_xm, hexbuf, ROW_STATS, 10, 2, ATTR_VALUE); ld a, #0x71 push af inc sp ld hl, #0x0002 push hl ld hl, #0xa04 push hl ld de, #_hexbuf ld hl, #_win_xm call _wc_prsrw_attr ;src/main.c:575: put_hex2(hexbuf, row); ld a, -5 (ix) push af inc sp ld hl, #_hexbuf call _put_hex2 ;src/main.c:576: wc_prsrw_attr(&win_xm, hexbuf, ROW_STATS, 19, 2, ATTR_VALUE); ld a, #0x71 push af inc sp ld hl, #0x0002 push hl ld hl, #0x1304 push hl ld de, #_hexbuf ld hl, #_win_xm call _wc_prsrw_attr ;src/main.c:578: put_dec3(decbuf, bpm); pop de push de ld hl, #_decbuf call _put_dec3 ;src/main.c:579: wc_prsrw_attr(&win_xm, decbuf, ROW_STATS, 27, 3, ATTR_VALUE); ld a, #0x71 push af inc sp ld hl, #0x0003 push hl ld hl, #0x1b04 push hl ld de, #_decbuf ld hl, #_win_xm call _wc_prsrw_attr ;src/main.c:581: put_time(timebuf, samples / 44100UL); ld hl, #0x0000 push hl ld hl, #0xac44 push hl ld e, -4 (ix) ld d, -3 (ix) ld l, -2 (ix) ld h, -1 (ix) call __divulong pop af ex (sp),hl push de ld hl, #_timebuf call _put_time ;src/main.c:582: wc_prsrw_attr(&win_xm, timebuf, ROW_TIME, 7, 5, ATTR_VALUE); ld a, #0x71 push af inc sp ld hl, #0x0005 push hl ld hl, #0x706 push hl ld de, #_timebuf ld hl, #_win_xm call _wc_prsrw_attr ;src/main.c:584: put_time(timebuf, total_samples / 44100UL); ld hl, #0x0000 push hl ld hl, #0xac44 push hl ld de, (_total_samples) ld hl, (_total_samples + 2) call __divulong pop af ex (sp),hl push de ld hl, #_timebuf call _put_time ;src/main.c:585: wc_prsrw_attr(&win_xm, timebuf, ROW_TIME, 15, 5, ATTR_VALUE); ld a, #0x71 push af inc sp ld hl, #0x0005 push hl ld hl, #0xf06 push hl ld de, #_timebuf ld hl, #_win_xm call _wc_prsrw_attr ;src/main.c:587: draw_progress_bar(samples, total_samples); ld hl, (_total_samples + 2) push hl ld hl, (_total_samples) push hl ld e, -4 (ix) ld d, -3 (ix) ld l, -2 (ix) ld h, -1 (ix) call _draw_progress_bar ;src/main.c:589: } ld sp, ix pop ix ret ;src/main.c:591: void main_start() ; --------------------------------- ; Function main_start ; --------------------------------- _main_start:: dec sp ;src/main.c:595: copy_file_name(); call _copy_file_name ;src/main.c:607: wc_prwow(&win_xm); ld hl, #_win_xm call _wc_prwow ;src/main.c:608: xm_draw_static_labels(); call _xm_draw_static_labels ;src/main.c:609: xm_set_status("Loading, please wait..."); ld hl, #___str_17 call _xm_set_status ;src/main.c:611: if (state_esp == 0xFF) ld a, (_state_esp) inc a jr nz, 00102$ ;src/main.c:612: state_esp = esp_init() ? 1 : 2; call _esp_init or a, a ld a, #0x01 jr nz, 00126$ ld a, #0x02 00126$: ld (#_state_esp), a 00102$: ;src/main.c:614: if (state_esp != 1) ld a, (_state_esp) dec a jr z, 00104$ ;src/main.c:616: error_esp(); inc sp jp _error_esp ;src/main.c:617: return; jp 00123$ 00104$: ;src/main.c:620: total_samples = 0; xor a, a ld (_total_samples+0), a ld (_total_samples+1), a ld (_total_samples+2), a ld (_total_samples+3), a ;src/main.c:622: if (!play_xm()) call _play_xm or a, a jr nz, 00109$ ;src/main.c:624: if (last_esp_status == ESP_ERR_OUT_OF_MEMORY) ld a, (_last_esp_status) sub a, #0x99 jr nz, 00106$ ;src/main.c:625: error_oom(); inc sp jp _error_oom jp 00123$ 00106$: ;src/main.c:627: error_playback(); inc sp ;src/main.c:628: return; jp _error_playback 00109$: ;src/main.c:631: xm_set_status("Playing"); ld hl, #___str_18 call _xm_set_status ;src/main.c:632: xm_draw_stats_labels(); call _xm_draw_stats_labels ;src/main.c:633: last_track_status = TRACK_OBJ_ST_PLAYING; ld hl, #_last_track_status ld (hl), #0x21 ;src/main.c:634: xm_update_info(); call _xm_update_info ;src/main.c:636: frame_ctr = 0; ld iy, #0 add iy, sp ld 0 (iy), #0x00 ;src/main.c:639: while (1) 00121$: ;src/main.c:643: __endasm; halt ;src/main.c:645: if (++frame_ctr >= 10) // ~5 updates/sec at 50Hz ld iy, #0 add iy, sp inc 0 (iy) ld a, 0 (iy) sub a, #0x0a jr c, 00111$ ;src/main.c:647: frame_ctr = 0; ld 0 (iy), #0x00 ;src/main.c:648: xm_update_info(); call _xm_update_info 00111$: ;src/main.c:651: if (wc_key_pgdn()) // PgDn - unload and go to next file call _wc_key_pgdn or a, a jr z, 00113$ ;src/main.c:652: unload_and_exit(WC_NEXT_FILE); ld a, #0x02 call _unload_and_exit 00113$: ;src/main.c:654: if (wc_key_pgup()) // PgUp - unload and go to previous file call _wc_key_pgup or a, a jr z, 00115$ ;src/main.c:655: unload_and_exit(WC_PREV_FILE); ld a, #0x04 call _unload_and_exit 00115$: ;src/main.c:657: if (wc_key_esc()) // Esc - unload and exit call _wc_key_esc or a, a jr z, 00117$ ;src/main.c:658: unload_and_exit(WC_EXIT); xor a, a call _unload_and_exit 00117$: ;src/main.c:660: if (wc_key_space()) // Space - leave the track playing, just exit call _wc_key_space or a, a jr z, 00121$ ;src/main.c:661: leave_playing_and_exit(); call _leave_playing_and_exit jp 00121$ 00123$: ;src/main.c:663: } inc sp ret ___str_17: .ascii "Loading, please wait..." .db 0x00 ___str_18: .ascii "Playing" .db 0x00 ;src/main.c:666: void main() ; --------------------------------- ; Function main ; --------------------------------- _main:: ;src/main.c:676: __endasm; ld (_ret_sp), sp ld (_call_type), a ld (_p_file_name), bc ex af, af ld (_file_ext), a ld (_filesize), hl ld (_filesize + 2), de ;src/main.c:678: switch (call_type) ld a, (_call_type+0) or a, a jp z, _main_start ld a, (_call_type) sub a, #0x03 jp z, _about ;src/main.c:680: case WC_CALL_EXT: ;src/main.c:681: main_start(); ;src/main.c:682: break; ;src/main.c:684: case WC_CALL_MENU: ;src/main.c:685: about(); ;src/main.c:686: break; ;src/main.c:688: default: ;src/main.c:689: wc_exit(WC_EXIT); xor a, a ;src/main.c:690: } ;src/main.c:691: } jp _wc_exit .area _CODE .area _INITIALIZER __xinit__state_esp: .db #0xff ; 255 .area _CABS (ABS)