User Tag List

Страница 9 из 12 ПерваяПервая ... 56789101112 ПоследняяПоследняя
Показано с 81 по 90 из 111

Тема: Кросскомпилятор Си под 8080

  1. #81

    Регистрация
    01.12.2010
    Адрес
    г. Санкт-Петербург
    Сообщений
    1,657
    Записей в дневнике
    21
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    3
    Поблагодарили
    2 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Обещал в среду, поэтому выкладываю что есть. Я сегодня, внезапно, опять с нуля переписал кодогенератор. Переписать до конца не успел и некоторые вещи компилируется не оптимально.

    При этом синтаксисом Си почти не занимался, там то же есть масса косяков.

    Косяки все не перечисляю, поскольку их там несколько десятков. Но основное это:

    1) Преобразование типов криво написано. Никакого автоматического преобразования нет. То есть signed -> unsigned, short -> char и т.п. При вычитании указателей деление на размер может не производится. Сравнение указателя с нулем не реализовано. Я просто не успел.

    2) Инициализация статических данных написана в самом простом варианте и не совсем корректно. ( uchar code[4] = { 1,2,3,4 }; )

    3) #define действует на #define

    4) Переменные и функции не контролируются на дубликаты.

    5) switch реализован криво. Забыл. (Два или более подряд идущих CASE быть не должно. Перед CASE должен быть BREAK, иначе поведение не определено)

    И по оптимизации основное:

    1) Операции && и || и ! работают крайне медленно. Хотя и корректно. Не успел дописать оптимизацию.

    2) Дублирующиеся бесполезные команды ассемблера будут удаляться на следующем этапе компиляции, который я еще не дописал.

    3) Размеры структур должны быть кратны степени двойки (но об этом и так вам сообщит компилятор)

    4) Не все варианты команд реализованы, есть вероятность схватить ошибку типа "pokeHL 12"

    P.S. Можете добавить в список, но у меня пока дел хватает и ошибки я правлю когда они сильно мешают жить.

    Во вложении компилятор и исходники игрушки. Игрушка тормозит не по детски, не синхронизируется с кадровой разверткой, но вроде работает. Для цветного Апогея.
    Вложения Вложения
    Последний раз редактировалось vinxru; 20.09.2012 в 00:46.

  2. #82

    Регистрация
    01.12.2010
    Адрес
    г. Санкт-Петербург
    Сообщений
    1,657
    Записей в дневнике
    21
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    3
    Поблагодарили
    2 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Пример кода

    Код:
    ;--- drawSprite -----------------------------------------------------------------
    drawSprite_x ds 1
    drawSprite_y ds 1
    drawSprite_s ds 2
    drawSprite_v ds 2
    drawSprite_a ds 1
    drawSprite:
      ld (drawSprite_s), hl
      ; 8 a = (uchar)(x/SPRITE_WIDTH*5);
      ld a, (drawSprite_x)
      rra
      rra
      and 3Fh
      ld d, 5
      call op_mul
      ld a, l
      ld (drawSprite_a), a
      ; 9 v = (uchar*)(0xA009 + 94*6 + a + y*94);
      ld hl, (drawSprite_a)
      ld h, 0
      ld de, 41533
      add hl, de
      push hl
      ld d, 94
      ld a, (drawSprite_y)
      call op_mul
      pop de
      add hl, de
      ld (drawSprite_v), hl
      ; 11 switch(x % SPRITE_WIDTH) {
      ld a, (drawSprite_x)
      and 3
      cp 0
      jp nz, l24
      ; 12 drawImage (v, CYAN, s); break;
      ld hl, (drawSprite_v)
      ld (drawImage_to), hl
      ld a, 129
      ld (drawImage_color), a
      ld hl, (drawSprite_s)
      call drawImage
      ; 12 break;
      jp l23
    l24:
      cp 1
      jp nz, l25
      ; 13 drawImage1(v, CYAN, s); break;
      ld hl, (drawSprite_v)
      ld (drawImage1_to), hl
      ld a, 129
      ld (drawImage1_color), a
      ld hl, (drawSprite_s)
      call drawImage1
      ; 13 break;
      jp l23
    l25:
      cp 2
      jp nz, l26
      ; 14 drawImage2(v, CYAN, s); break;
      ld hl, (drawSprite_v)
      ld (drawImage2_to), hl
      ld a, 129
      ld (drawImage2_color), a
      ld hl, (drawSprite_s)
      call drawImage2
      ; 14 break;
      jp l23
    l26:
      cp 3
      jp nz, l27
      ; 15 drawImage3(v, CYAN, s); break;
      ld hl, (drawSprite_v)
      ld (drawImage3_to), hl
      ld a, 129
      ld (drawImage3_color), a
      ld hl, (drawSprite_s)
      call drawImage3
      ; 15 break;
      jp l23
    l23:
    l27:
      ; 18 a = (uchar)((y/SPRITE_WIDTH)*MAP_WIDTH+(x/SPRITE_HEIGHT));
      ld a, (drawSprite_y)
      rra
      rra
      and 3Fh
      ld h, 0
      ld l, a
      add hl, hl
      add hl, hl
      add hl, hl
      add hl, hl
      ld a, (drawSprite_x)
      rra
      rra
      and 3Fh
      ld e, a
      ld d, 0
      add hl, de
      ld a, l
      ld (drawSprite_a), a
      ; 19 map1[a]=0xFF;
      ld hl, (drawSprite_a)
      ld h, 0
      ld de, map1
      add hl, de
      ld a, 255
      ld (hl), a
      ; 20 if(x%MAP_WIDTH) {
      ld a, (drawSprite_x)
      and 0Fh
      or a
      jp z, l28
      ; 21 map1[a+1] = 0xFF;
      ld a, (drawSprite_a)
      add 1
      ld h, 0
      ld l, a
      ld de, map1
      add hl, de
      ld a, 255
      ld (hl), a
      ; 22 if(y%MAP_WIDTH) {
      ld a, (drawSprite_y)
      and 0Fh
      or a
      jp z, l29
      ; 23 map1[a+MAP_WIDTH]=0xFF;
      ld a, (drawSprite_a)
      add 16
      ld h, 0
      ld l, a
      ld de, map1
      add hl, de
      ld a, 255
      ld (hl), a
      ; 24 map1[a+(MAP_WIDTH+1)]=0xFF;
      ld a, (drawSprite_a)
      add 17
      ld h, 0
      ld l, a
      ld de, map1
      add hl, de
      ld a, 255
      ld (hl), a
    l29:
      jp l30
    l28:
      ; 27 if(y%MAP_WIDTH) {
      ld a, (drawSprite_y)
      and 0Fh
      or a
      jp z, l31
      ; 28 map1[a+MAP_WIDTH]=0xFF;
      ld a, (drawSprite_a)
      add 16
      ld h, 0
      ld l, a
      ld de, map1
      add hl, de
      ld a, 255
      ld (hl), a
    l31:
    l30:
    l22:
      ret
    ;--- redrawTiles -----------------------------------------------------------------
    redrawTiles_v ds 2
    redrawTiles_a ds 1
    redrawTiles_addr ds 1
    redrawTiles:
      push bc
      ; 39 for(m = map1; m - (map1+MAP_WIDTH*MAP_HEIGHT); ++m) {
      ld bc, map1
    l33:
      ld hl, -((map1)+(208))
      add hl, bc
      ld a, l
      or h
      jp z, l34
      ; 40 if(!*m) continue;
      ld a, (bc)
      or a
      jp nz, l37
      ; 40 continue;
      jp l35
    l37:
      ; 41 *m = 0;
      xor a
      ld (bc), a
      ; 43 addr = (uchar)(m - map1);
      ld hl, -(map1)
      add hl, bc
      ld a, l
      ld (redrawTiles_addr), a
      ; 44 a = map[addr];
      ld hl, (redrawTiles_addr)
      ld h, 0
      ld de, map
      add hl, de
      ld a, (hl)
      ld (redrawTiles_a), a
      ; 45 v = (uchar*)(0xA009 + 94*6 + (addr/MAP_WIDTH)*(94*4) + 5*(addr%MAP_WIDTH));
      ld a, (redrawTiles_addr)
      rra
      rra
      rra
      rra
      and 0Fh
      ld de, 376
      ld h, 0
      ld l, a
      call op_mul16
      ld de, 41533
      add hl, de
      ld a, (redrawTiles_addr)
      and 0Fh
      push hl
      ld d, a
      ld a, 5
      call op_mul
      pop de
      add hl, de
      ld (redrawTiles_v), hl
      ; 46 if(a==0) { 
      ld a, (redrawTiles_a)
      cp 0
      jp nz, l39
      ; 47 drawEmptyImage(v);
      ld hl, (redrawTiles_v)
      call drawEmptyImage
      jp l40
    l39:
      ; 49 if(a >= 0x80) a=2;
      ld a, (redrawTiles_a)
      cp 128
      jp c, l42
      ; 49 a=2;
      ld a, 2
      ld (redrawTiles_a), a
    l42:
      ; 50 a--;
      ld hl, redrawTiles_a
      ld a, (hl)
      dec (hl)
      ; 51 drawImage(v, tilesColors[a], tiles + a*16);
      ld hl, (redrawTiles_v)
      ld (drawImage_to), hl
      ld hl, (redrawTiles_a)
      ld h, 0
      ld de, tilesColors
      add hl, de
      ld a, (hl)
      ld (drawImage_color), a
      ld hl, (redrawTiles_a)
      ld h, 0
      add hl, hl
      add hl, hl
      add hl, hl
      add hl, hl
      ld de, tiles
      add hl, de
      call drawImage
    l40:
    l35:
      inc bc
      jp l33
    l34:
    l32:
      pop bc
      ret
    ;--- redrawScreen -----------------------------------------------------------------
    redrawScreen_i ds 1
    redrawScreen_s ds 2
    redrawScreen:
      push bc
      ; 61 redrawTiles();
      call redrawTiles
      ; 63 s = enemySprite + enemyAnimation[(ticks/4)%4];
      ld a, (ticks)
      rra
      rra
      and 3Fh
      and 3
      ld h, 0
      ld l, a
      ld de, enemyAnimation
      add hl, de
      ld l, (hl)
      ld h, 0
      ld de, enemySprite
      add hl, de
      ld (redrawScreen_s), hl
      ; 64 for(e=enemies, i=0; i<enemyCount; ++i, ++e) 
      ld bc, enemies
      xor a
      ld (redrawScreen_i), a
    l44:
      ld hl, enemyCount
      ld a, (redrawScreen_i)
      cp (hl)
      jp nc, l45
      ; 65 drawSprite(e->x, e->y, s);
      ld a, (bc)
      ld (drawSprite_x), a
      ld hl, bc
      inc hl
      ld a, (hl)
      ld (drawSprite_y), a
      ld hl, (redrawScreen_s)
      call drawSprite
    l46:
      ld hl, redrawScreen_i
      inc (hl)
      inc bc
      inc bc
      inc bc
      inc bc
      jp l44
    l45:
      ; 67 if(playerDir==1 || playerDir==2) s = playerSprite + 16 + 16*(1 + (ticks / 2)&1); else
      ld a, (playerDir)
      cp 1
      ld a, 1
      jp z, l48
      dec a
    l48:
      push af
      ld a, (playerDir)
      cp 2
      ld a, 1
      jp z, l49
      dec a
    l49:
      ld d, a
      pop af
      or d
      or a
      jp z, l50
      ; 67 s = playerSprite + 16 + 16*(1 + (ticks / 2)&1); else
      ld a, (ticks)
      cp a
      rra
      add 1
      and 1
      ld d, a
      ld a, 16
      call op_mul
      ld de, (playerSprite)+(16)
      add hl, de
      ld (redrawScreen_s), hl
      jp l51
    l50:
      ; 68 if(playerDir==3 || playerDir==4) s = playerSprite + 16*3 + 16*(1 + (ticks / 2)&1);
      ld a, (playerDir)
      cp 3
      ld a, 1
      jp z, l52
      dec a
    l52:
      push af
      ld a, (playerDir)
      cp 4
      ld a, 1
      jp z, l53
      dec a
    l53:
      ld d, a
      pop af
      or d
      or a
      jp z, l54
      ; 68 s = playerSprite + 16*3 + 16*(1 + (ticks / 2)&1);
      ld a, (ticks)
      cp a
      rra
      add 1
      and 1
      ld d, a
      ld a, 16
      call op_mul
      ld de, (playerSprite)+(48)
      add hl, de
      ld (redrawScreen_s), hl
      jp l55
    l54:
      ; 69 s = playerSprite;
      ld hl, playerSprite
      ld (redrawScreen_s), hl
    l55:
    l51:
      ; 70 drawSprite(playerX, playerY, s);
      ld a, (playerX)
      ld (drawSprite_x), a
      ld a, (playerY)
      ld (drawSprite_y), a
      ld hl, (redrawScreen_s)
      call drawSprite
    l43:
      pop bc
      ret
    ;--- getKeybFire -----------------------------------------------------------------
    getKeybFire:
      ; 2 *(uchar*)0xED00 = ~(1<<7);  
      ld a, 127
      ld (60672), a
      ; 3 return !(*(uchar*)0xED01 & 0x80);  
      ld a, (60673)
      and 128
      or a
      ld a, 0
      jp nz, l57
      inc a
    l57:
      jp l56
    l56:
      ret
    ;--- getKeybArrows -----------------------------------------------------------------
    getKeybArrows:
      ; 7 *(uchar*)0xED00 = ~(1<<1);  
      ld a, 253
      ld (60672), a
      ; 8 return ~(*(uchar*)0xED01);  
      ld a, (60673)
      cpl
      jp l58
    l58:
      ret
    lvd:
      db 35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,32
      db 35,32,32,32,55,32,32,50,32,32,32,32,32,32,35,32
      db 35,32,35,32,35,32,35,50,35,32,35,32,35,32,35,32
      db 35,32,32,32,32,54,50,50,32,32,32,50,32,32,35,32
      db 35,32,35,32,35,50,35,32,35,32,35,50,35,32,35,32
      db 35,52,50,54,50,50,32,32,32,54,50,50,50,32,35,32
      db 35,32,35,64,35,50,35,32,35,50,35,32,35,32,35,32
      db 35,32,50,32,32,50,64,32,32,32,50,32,32,32,35,32
      db 35,50,35,50,35,50,35,54,35,50,35,32,35,32,35,32
      db 35,32,32,32,32,50,32,32,32,50,32,64,54,32,35,32
      db 35,50,35,32,35,32,35,50,35,50,35,50,35,32,35,32
      db 35,32,50,32,32,32,50,64,32,32,32,32,32,32,35,32
      db 35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,32
    ;--- printKeyb -----------------------------------------------------------------
    printKeyb:
      push bc
      ; 52 for(x=0; x<8; x++) {
      ld b, 0
    l60:
      ld a, b
      cp 8
      jp nc, l61
      ; 53 *(uchar*)0xED00 = ~(1<<x);  
      ld d, b
      ld a, 1
      call op_shl
      cpl
      ld (60672), a
      ; 54 for(y=0; y<8; y++)
      ld c, 0
    l64:
      ld a, c
      cp 8
      jp nc, l65
      ; 55 ((uchar*)0xA000+94*y)[x] = (*(uchar*)0xED01 >> y) & 1;
      ld d, c
      ld a, 94
      call op_mul
      ld de, 40960
      add hl, de
      ld e, b
      ld d, 0
      add hl, de
      ld d, c
      ld a, (60673)
      call op_shr
      and 1
      ld (hl), a
    l66:
      ld a, c
      inc c
      jp l64
    l65:
    l62:
      ld a, b
      inc b
      jp l60
    l61:
    l59:
      pop bc
      ret
    moveBonus:  ds 1
    moveExit:  ds 1
    moveDead:  ds 1

  3. #83

    Регистрация
    01.12.2010
    Адрес
    г. Санкт-Петербург
    Сообщений
    1,657
    Записей в дневнике
    21
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    3
    Поблагодарили
    2 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    В следующей версии будет часть ошибок поправлена и оптимизатор-удалятор подключен. Он так же сможет формировать программу в мненониках 8080.
    Последний раз редактировалось vinxru; 20.09.2012 в 14:43.

  4. #84

    Регистрация
    08.01.2012
    Адрес
    г.Винница, Украина
    Сообщений
    94
    Спасибо Благодарностей отдано 
    1
    Спасибо Благодарностей получено 
    21
    Поблагодарили
    16 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Работа проделана огромная! Молодец! Будем следить!

  5. #85

    Регистрация
    24.08.2007
    Адрес
    Днепропетровская обл.
    Сообщений
    1,681
    Спасибо Благодарностей отдано 
    2,712
    Спасибо Благодарностей получено 
    170
    Поблагодарили
    130 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Присоединяюсь. Браво! Даже не ожидал, что в наше время возможна разработка проекта такой сложности на чистом энтузиазме.

    Сравнительно просто можно реализовать в Вашем компиляторе оптимизацию, которая встречается редко в каком компиляторе, сделанном не большой фирмой за финансирование. Способ основан на отслеживании кодогенератором состояния процессора: флагов, регистров и т.д. Имея и актуализируя после генерации каждой команды набор такой информации, легко встроить различные оптимизации: загрузки адресов, значений, опора на состояние флагов (ну раз значение точно известно) и т.д. Заведите “слово состояния процессора”, представляющее собой запись (структуру в Си-терминологии) состояния различных флагов, регистров и т.п., что будет выглядеть примерно так:
    Код:
    TYPE
      FlagStatus = SET; (* Off, On, Unknown *)
    
    VAR
      cpuStat = RECORD
        flagZ, flagC, flagM ... : FlagStatus; (* Статус флагов *)
        regA, regB, regC ... : BOOLEAN; (* Есть ли в регистре точно известное значение? *)
        regA_val, regB_val, regC_val ... : INTEGER; (* Если оно есть, то значение RegX_val имеет смысл *)
      END;
    Теперь, допустим, нам по коду надо обнулить переменную var1. Делать мы это решили через засылку значения в неё из регистра A. Проверяем, а может в A уже ноль?
    Код:
    IF regA & (regA_val = 0) THEN
      (* Можно не генерировать обнуление, т.к. в A остался ноль, сформированный предыдущим кодом... *)
    ELSE
      Gen("XRA A");
      (* Теперь скорректируем состояние процессора, вызванное командой XRA A *)
      cpuStat.flagZ := On; cpuStat.regA := TRUE; cpuStat.regA_val := 0; ...
    END;
    Gen("STA var1");
    Или надо загрузить в HL адрес переменной varB, а там загружен адрес varA, которые идут подряд (отличаются единичкой):
    Код:
    IF regHL & (regHL_val = varA_addr) THEN
      (* Можно не генерировать установку адреса, он уже там... *)
    ELSIF regHL & (regHL_val = varA_addr + 1) THEN (* Адрес в HL, но он на единицу меньше, чем надо *)
      Gen("INX H");
    ELSIF regHL & (regHL_val = varA_addr - 1) THEN (* Адрес в HL, но он на единицу больше, чем надо *)
      Gen("DCX H");
    ELSE (* Что ни пробовали, но таки надо грузить адрес в HL... *)
      Gen("LXI H, varA");
    END;
    Извиняюсь, если где перепутал мнемонику, давно для РК-86 не кодил.

    P.S. Игру в эмуле Башкирия-2М запустить удалось только в ч/б. Выбираю при старте цветной Апогей, но после открытия файла он упрямо переключается на ч/б (буковка Ц пропадает из заголовка). Что я делаю не так?

  6. #86

    Регистрация
    07.08.2008
    Адрес
    г. Уфа
    Сообщений
    8,391
    Спасибо Благодарностей отдано 
    763
    Спасибо Благодарностей получено 
    2,367
    Поблагодарили
    1,317 сообщений
    Mentioned
    38 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Oleg N. Cher Посмотреть сообщение
    Выбираю при старте цветной Апогей, но после открытия файла он упрямо переключается на ч/б (буковка Ц пропадает из заголовка).
    Вы наверно через File->Open открываете, а при этом, в соответствии с EMU.ext запускается конфиг Apogee. Можно или EMU.ext изменить или грузить в конфиге цветного апогея командой I -> появится диалог, выбираете test_ok.rka и G.

  7. #87

    Регистрация
    24.08.2007
    Адрес
    Днепропетровская обл.
    Сообщений
    1,681
    Спасибо Благодарностей отдано 
    2,712
    Спасибо Благодарностей получено 
    170
    Поблагодарили
    130 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    В игре есть "баг" или "фича": если при движении вниз человечка не отпускать кнопку движения, он проходит немного вправо (если открыт путь). Влево же такого поведения не наблюдается. Заметил: редко-редко при нажатии кнопки движения человечек делает шажок не в ту сторону, но потом сам возвращается. Управлять легко, не зацепляется за края стен. Удобно. Осталось поправить мерцание спрайтов.

  8. #88

    Регистрация
    01.12.2010
    Адрес
    г. Санкт-Петербург
    Сообщений
    1,657
    Записей в дневнике
    21
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    3
    Поблагодарили
    2 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Oleg N. Cher Посмотреть сообщение
    P.S. Игру в эмуле Башкирия-2М запустить удалось только в ч/б. Выбираю при старте цветной Апогей, но после открытия файла он упрямо переключается на ч/б (буковка Ц пропадает из заголовка). Что я делаю не так?
    Да, спасибо больше. Я так и собираюсь делать. И еще много будет всяких оптимизаций. Например замена JMP, который переходит на JMP. Замена PUSH H, POP H на XCHG, XCHG. Поиск одинаковых фрагментов кода и вынесение из в функцию.

    Но пока я делаю страшную вещь... Прошлая версия компилятора собирала любую команду в три этапа: загрузка первого аргумента в HL, загрузка второго аргумента в DE, работа с регистрами. Этот подход работает, но код не оптимален и сложно поддается оптимизации.

    Например ushort &= register uchar*

    ;oSAnd pConstStrRef16 pBCRef8
    ld a, (bc)
    ld e, c
    ld d, 0
    ld hl, (name1)
    ld a, l
    and e
    ld l, a
    ld a, h
    and d
    ld h, a
    ld (name1), hl

    Я объединил эти три действия в одно и получил под тысячу вариантов команд. И сейчас сижу описываю более оптимальные варианты

    ld hl, name1
    ld a, (bc)
    and (hl)
    ld (hl), a
    inc hl
    ld (hl), 0

    ---------- Post added at 23:11 ---------- Previous post was at 22:58 ----------

    Цитата Сообщение от Oleg N. Cher Посмотреть сообщение
    Осталось поправить мерцание спрайтов.
    Алгоритм отрисовки неправильный выбран. Но это потому что эта игра перенесена в JS. При перемещении спрайтов надо просто закрашивать лишнее черным не перерисовывая всю карту.
    Последний раз редактировалось vinxru; 21.09.2012 в 23:07.

  9. #89

    Регистрация
    01.12.2010
    Адрес
    г. Санкт-Петербург
    Сообщений
    1,657
    Записей в дневнике
    21
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    3
    Поблагодарили
    2 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Вот это это выглядит. Код для 8 битного вычитания.

    Для команд & | ^ + > < <= >= != == будет подобный вариант, но там команды будут проще, так как там слогаемые можно переставлять:

    case pC, pA: w.ld_d_a().ld_a_c().alu_d(op); break;

    заменится на

    case pC, pA: w.alu_с(op); break;

    Код:
    void cmd_alu(AluOp op, bool self, bool flags) {
      Stack& a = stack[stack.size()-2];
      Stack& b = stack[stack.size()-1];
    
      Place ap = simpleArg8(a.place);
      Place bp = simpleArg8(b.place);
    
      Writer& w = bc();
    
      if(ap!=pA && bp!=pA) 
        useA();
    
      switch(ap) {
        case pA:
          switch(bp) {
            case pB:                          w.alu_b(op); break;
            case pC:                          w.alu_c(op); break;
            case pHL:                         w.alu_l(op); break;
            case pConst:                      w.alu(op, b); break;
            case pConstRef8:         useHL(); w.ld_hl(b).alu_HL(op); break;
            case pConstStrRefRef8:   useHL(); w.ld_hl_ref(b).alu_HL(op); break;
            case pHLRef8:                     w.alu_HL(op); break;
            case pBCRef8:            useHL(); w.ld_hl_bc().alu_HL(op); break;
            case pStack8:                     w.pop_de().alu_d(op); break;
            case pStack16:                    w.pop_de().alu_e(op); break;
            case pStackRef8:         chkHL(); w.pop_hl().alu_HL(op); break;
            default: cmd_alu_raise(ap, bp);
          }
          break;
        case pB:
          switch(bp) {
            case pA:                          w.ld_d_a().ld_a_b().alu_d(op); break;
            case pB:                          w.ld_a_b().alu_b(op); break;
            case pC:                          w.ld_a_b().alu_c(op); break;
            case pHL:                         w.ld_a_b().alu_l(op); break;
            case pConst:                      w.ld_a_b().alu(op, b); break;
            case pConstRef8:                  w.ld_a_b().ld_hl(b).alu_HL(op); break;
            case pConstStrRefRef8:   useHL(); w.ld_a_b().ld_hl_ref(b).alu_HL(op); break;
            case pHLRef8:                     w.ld_a_b().alu_HL(op); break;
            case pBCRef8:                     w.ld_a_BC().ld_d_a().ld_a_b().alu_d(op); break;
            default: cmd_alu_raise(ap, bp);
          }
          break;
        case pC:
          switch(bp) {
            case pA:                          w.ld_d_a().ld_a_c().alu_d(op); break;
            case pB:                          w.ld_a_c().alu_b(op); break;
            case pC:                          w.ld_a_c().alu_c(op); break;
            case pHL:                         w.ld_a_c().alu_l(op); break;
            case pConst:                      w.ld_a_c().alu(op, b); break;
            case pConstRef8:                  w.ld_a_c().ld_hl(b).alu_HL(op); break;
            case pConstStrRefRef8:   useHL(); w.ld_a_c().ld_hl_ref(b).alu_HL(op); break;
            case pHLRef8:                     w.ld_a_c().alu_HL(op); break;
            case pBCRef8:                     w.ld_a_BC().ld_d_a().ld_a_b().alu_d(op); break;
            default: cmd_alu_raise(ap, bp);
          }
          break;
        case pHL:
          switch(bp) {
            case pA:                          w.ld_d_a().ld_a_l().alu_d(op); break;
            case pB:                          w.ld_a_l().alu_b(op); break;
            case pC:                          w.ld_a_l().alu_c(op); break;
            case pConst:                      w.ld_a_l().alu(op, b); break;
            case pConstRef8:                  w.ld_a_l().ld_hl(b).alu_HL(op); break;
            case pConstStrRefRef8:            w.ld_a_l().ld_hl_ref(b).alu_HL(op); break;
            case pBCRef8:                     w.ld_a_BC().ld_d_a().ld_a_l().alu_d(op); break;
            default: cmd_alu_raise(ap, bp);
          }
          break;
        case pConst:
          switch(bp) {
            case pA:                          w.ld_d_a().ld_a(a).alu_d(op); break;
            case pB:                          w.ld_a(a).alu_b(op); break;
            case pC:                          w.ld_a(a).alu_c(op); break;
            case pHL:                         w.ld_a(a).alu_l(op); break;
            case pConstRef8: if(lastHL==-1) { w.ld_hl(b).ld_a(a).alu_HL(op); break; } // 10+7+7=24 
                                              w.ld_a_ref(b).ld_d_a().ld_a(a).alu_d(op); break; // 13+5+7+7=32
            case pConstStrRefRef8:   useHL(); w.ld_hl_ref(b).ld_a(a).alu_HL(op); break;
            case pHLRef8:                     w.ld_a(a).alu_HL(op); break;
            case pBCRef8:                     w.ld_a_BC().ld_d_a().ld_a(a).alu_d(op); break; // это 7+5+7+4=23, против ld_hl_bc().ld_a(a).alu_HL(op), которым еще нужен HL
            default: cmd_alu_raise(ap, bp);
          }
          break;
        case pConstRef8:
          switch(bp) {
            case pA:                          w.ld_d_a().ld_a_ref(a).alu_d(op); break;
            case pB:                          w.ld_a_ref(a).alu_b(op); break;
            case pC:                          w.ld_a_ref(a).alu_c(op); break;
            case pHL:                         w.ld_a_ref(a).alu_l(op); break;
            case pConst:                      w.ld_a_ref(a).alu(op, b); break;
            case pConstRef8: if(lastHL==-1) { w.ld_hl(b).ld_a_ref(a).alu_HL(op); break; } // 10+13+7=30
                                              w.ld_a_ref(b).ld_d_a().ld_a_ref(a).alu_d(op); break; // 13+5+13+4=35
            case pConstStrRefRef8:   useHL(); w.ld_hl_ref(b).ld_a_ref(a).alu_HL(op); break; // 16+13+7=36
            case pHLRef8:                     w.ld_a_ref(a).alu_HL(op); break;
            case pBCRef8:                     w.ld_a_BC().ld_d_a().ld_a_ref(a).alu_d(op); break;
            default: cmd_alu_raise(ap, bp);
          }
          break;
        case pConstStrRefRef8:
          switch(bp) {
            case  pA:               useHL(); w.ld_d_a()                         .ld_hl_ref(a).ld_a_HL().alu_d(op); break;
            case  pB:               useHL(); w                                  .ld_hl_ref(a).ld_a_HL().alu_b(op); break;
            case  pC:               useHL(); w                                  .ld_hl_ref(a).ld_a_HL().alu_c(op); break;
            case  pHL:                       w.ld_d_l()                         .ld_hl_ref(a).ld_a_HL().alu_d(op); break;
            case  pConst:           useHL(); w                                  .ld_hl_ref(a).ld_a_HL().alu(op,b); break;
            case  pConstRef8:       useHL(); if(self) { w.ld_hl(a)    .ld_d_HL().ld_hl_ref(a).ld_a_HL().alu_d(op); break; } // 10+7+16+7+4 = 44
                                    w.ld_hl_ref(a).ld_a_HL().ld_hl(b).alu_HL(op); break;                                    // 16+7+10+7   = 40
            case  pConstStrRefRef8: useHL(); if(self) { w.ld_hl_ref(a).ld_d_HL().ld_hl_ref(a).ld_a_HL().alu_d(op); break; } // 16+7+16+7+4 = 50
                                    w.ld_hl_ref(a).ld_a_HL().ld_hl_ref(b).alu_HL(op); break;                                // 16+7+16+7   = 46
            case  pHLRef8:                   w.ld_d_HL()                        .ld_hl_ref(a).ld_a_HL().alu_d(op); break;
            case  pBCRef8:          useHL(); w.ld_a_BC().ld_d_a()               .ld_hl_ref(a).ld_a_HL().alu_d(op); break;
            default: cmd_alu_raise(ap, bp);
          }
          a.place = a.place==pConstStrRefRef8 ? pHLRef8 : pHLRef16; // Оптимизация
          lastHL = stack.size()-2;
          break;
        case pHLRef8: // Если self, то HL изменять нельзя
          switch(bp) {
            case pA:                        w.ld_d_a()              .ld_a_HL().alu_d(op); break;
            case pB:                        w                       .ld_a_HL().alu_b(op); break;
            case pC:                        w                       .ld_a_HL().alu_c(op); break;
            case pConst:                    w                       .ld_a_HL().alu(op,b); break;
            case pConstRef8:                w.ld_a_ref(b).ld_d_a()  .ld_a_HL(); break;
            case pConstStrRefRef8:if(self){ w.ex_hl_de().ld_hl_ref(b).ld_h_HL().ex_hl_de().ld_a_HL().alu_d(op); break; }
                                            w.ld_a_HL().ld_hl_ref(b).alu_HL(op); break;
            case pBCRef8:                   w.ld_a_BC().ld_d_a()    .ld_a_HL().alu_d(op); break;
            default: cmd_alu_raise(ap, bp);
          }
          break;
        case pBCRef8:
          switch(bp) {
            case pA:                        w.ld_d_a()              .ld_a_BC().alu_d(op);  break;
            case pB:                        w                       .ld_a_BC().alu_b(op);  break;
            case pC:                        w                       .ld_a_BC().alu_c(op);  break;
            case pHL:                       w                       .ld_a_BC().alu_l(op);  break;
            case pConst:                    w                       .ld_a_BC().alu(op,b);  break;
            case pConstRef8:if(lastHL==-1){ w.ld_hl(b)              .ld_a_BC().alu_HL(op); break; } // 10+7+7 = 24
                                            w.ld_a_ref(b).ld_d_a()  .ld_a_BC().alu_d(op);  break; // 13+5+7+4 = 29                             
            case pConstStrRefRef8: useHL(); w.ld_hl_ref(b)          .ld_a_BC().alu_HL(op); break;
    .... Съедено сайтом ...
        default: cmd_alu_raise(ap, bp);
      }
      if(self) {
        switch(a.place) {
          case pConstStrRef8:
          case pConstRef8: w.ld_ref_a(a); break;
          case pHLRef8:    w.ld_HL_a();   break;
          case pBCRef8:    w.ld_BC_a();   break;
          default: cmd_alu_self_raise(a.place, bp);
        }
        asm_pop();
        if(flags) raise("flags!");
      } else {
        asm_pop();
        asm_pop();
        if(flags) stack.push_backr().place = pFlags;
             else popTmpA();
      }
    }
    Последний раз редактировалось vinxru; 21.09.2012 в 23:34.

  10. #90

    Регистрация
    08.01.2012
    Адрес
    г.Винница, Украина
    Сообщений
    94
    Спасибо Благодарностей отдано 
    1
    Спасибо Благодарностей получено 
    21
    Поблагодарили
    16 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    vinxru, тебе ещё все предстоит в очередной раз переделывать, когда будешь вести по каждой переменной её состояние, и в зависимости от этого код будет разный. Приблизительный пример.
    Твой код, сейчас:
    Код:
      ; 54 for(y=0; y<8; y++)
      ld c, 0
    l64:
      ld a, c
      cp 8
      jp nc, l65
    ...
    
    l66:
      ld a, c
      inc c
      jp l64
    l65:
    Тут есть два варианта - если условие по старту верное (как в этом коде), то такой код неоптимален, и лучше что-то типа:

    Код:
      ; 54 for(y=0; y<8; y++)
      ld c, 0
    l64:
    ...
    
    
      ld a, c
      inc c
      cp 7
      jp c, l64
    а вот если условие неопределённое, то нужен такой код как есть.
    Нужно на каждую переменную вести её последнее значение, на этапе компиляции анализировать условия (y<8 в данном случае). И в зависимости от этого анализа условия компилятор выбирает нужную ветку.

    Ты молодец, много сделал, но тут ещё копать и копать. И боюсь, ещё не раз придётся всё переписать...

Страница 9 из 12 ПерваяПервая ... 56789101112 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Ассемблер 8080
    от Kakos_nonos в разделе Утилиты
    Ответов: 0
    Последнее: 21.09.2011, 23:35
  2. Продам пару платок с процами 8080
    от RedLine в разделе Барахолка (архив)
    Ответов: 15
    Последнее: 23.12.2010, 18:39
  3. схема АОН на 8080/z80
    от sergey2b в разделе Разный софт
    Ответов: 7
    Последнее: 07.02.2010, 22:43
  4. An 8080/Z80 C Compiler
    от breeze в разделе Программирование
    Ответов: 1
    Последнее: 18.08.2005, 06:54

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •